Проблема с созданным классом LINQ и IEnumerable в Excel - PullRequest
1 голос
/ 27 апреля 2010

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

Метод:

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();
    }

Мой маленький тестовый класс:

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

Два использования:

Успех

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. Для моего странного класса это работает отлично.

Почему?

Спасибо ...

1 Ответ

0 голосов
/ 27 апреля 2010

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

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

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

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

Кроме того, ваш вложенный foreach использует 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).

...