2010-04-26 1 views
1

Я написал метод, который экспортирует значения в файл excel из параметра IEnumerable. Метод работал отлично для моего небольшого тестового класса, и я был доволен, пока не проверил свой метод с классом LINQ.Проблема с LINQ Сгенерированный класс и IEnumerable в Excel

Метод:

public static void IEnumerableToExcel<T>(IEnumerable<T> data, HttpResponse Response) 
    { 
     Response.Clear(); 
     Response.ContentEncoding = System.Text.Encoding.Default; 
     Response.Charset = "windows-1254"; 
     // set MIME type to be Excel file. 
     Response.ContentType = "application/vnd.ms-excel;charset=windows-1254"; 
     // add a header to response to force download (specifying filename) 
     Response.AddHeader("Content-Disposition", "attachment;filename=\"ResultFile.xls\""); 

     Type typeOfT = typeof(T); 
     List<string> result = new List<string>(); 

     FieldInfo[] fields = typeOfT.GetFields(); 
     foreach (FieldInfo info in fields) 
     { 
      result.Add(info.Name);    
     } 

     Response.Write(String.Join("\t", result.ToArray()) + "\n"); 

     foreach (T t in data) 
     { 
      result.Clear(); 
      foreach (FieldInfo f in fields) 
       result.Add((typeOfT).GetField(f.Name).GetValue(t).ToString()); 
      Response.Write(String.Join("\t", result.ToArray()) + "\n"); 
     } 
     Response.End(); 
    } 

My Little Test Класс:

public class Mehmet 
{ 
    public string FirstName; 
    public string LastName;  
} 

Два Usage:

Success:

Mehmet newMehmet = new Mehmet(); 
     newMehmet.FirstName = "Mehmet"; 
     newMehmet.LastName = "Altiparmak"; 
     List<Mehmet> list = new List<Mehmet>(); 
     list.Add(newMehmet); 
     DeveloperUtility.Export.IEnumerableToExcel<Mehmet>(list, Response); 

Сбой:

ExtranetDataContext db = new ExtranetDataContext(); 
     DeveloperUtility.Export.IEnumerableToExcel<User>(db.Users, Response); 

Причина отказа: когда код достигает блока кода, используемого для получения полей шаблона (T), он не может найти какое-либо поле для класса LINQ Generated User. Для моего странного класса он отлично работает.

Почему?

Благодаря ...

ответ

0

классов, порожденных LINQ к SQL хранилища данных в частных полях (имя которого начинается с символа подчеркивания), в то время как ваш класс выборки предоставляет данные в открытых полях. Перегрузка используемого вами метода GetFields возвращает только общедоступные поля, поэтому он будет работать для вашего класса, но не для классов, сгенерированных LINQ to SQL.

Хорошая практика в .NET заключается в том, чтобы предоставлять данные как общедоступные свойства, поэтому наилучшим способом исправить ваш метод было бы перейти от использования полей к использованию свойств. Вам нужно будет изменить GetFields на GetProperties (который возвращает PropertyInfo[]). Тогда он будет работать для LINQ к SQL созданных классов и для классов, которые вы пишете, как это (с помощью автоматических свойств в C# 3.0):

public class Mehmet { 
    public string FirstName { get; set; } 
    public string LastName { get; set; }  
} 

В качестве альтернативы, можно использовать как GetFields и GetProperties, но так как хорошо продуманный класс не должны содержать публичные поля, это не обязательно.

Кроме того, ваш вложенная Еогеасп использует GetField в несколько странным образом:

foreach (FieldInfo f in fields) 
    result.Add((typeOfT).GetField(f.Name).GetValue(t).ToString()); 

// You don't need 'GetFied' because 'f' is the field you're looking for: 

foreach (FieldInfo f in fields) 
    result.Add(f.GetValue(t).ToString()); 

Для PropertyInfo, это будет выглядеть так же (вы будете использовать только PropertyInfo вместо этого).

Смежные вопросы