简体   繁体   English

LINQ生成的类和IEnumerable到Excel的问题

[英]Problem with LINQ Generated class and IEnumerable to Excel

I wrote a method which exports values to excel file from an IEnumerable parameter. 我写了一种从IEnumerable参数将值导出到excel文件的方法。 Method worked fine for my little test class and i was happy till i test my method with a LINQ class. 在我的小测试类中,方法工作得很好,直到我用LINQ类测试我的方法,我都很高兴。

Method: 方法:

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 Class: 我的小测验班:

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

Two 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);

Fail: 失败:

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

Fail Reason: When the code reaches the code block used to get the fields of the template(T), it can not find any field for the LINQ Generated User class. 失败原因:当代码到达用于获取template(T)字段的代码块时,它找不到LINQ Generated User类的任何字段。 For my weird class it works fine. 对于我的怪异类,它工作正常。

Why? 为什么?

Thanks... 谢谢...

Classes generated by LINQ to SQL store the data in private fields (whose name starts with underscore), while your sample class exposes the data in public fields. LINQ to SQL生成的类将数据存储在私有字段中(其名称以下划线开头),而您的示例类将数据公开在公共字段中。 The overload of the GetFields method that you are using returns only public fields, so it will work for your class, but not for LINQ to SQL generated classes. 您正在使用的GetFields方法的重载仅返回公共字段,因此它将对您的类有效,但不适用于LINQ to SQL生成的类。

A good practice in .NET is to expose data as public properties, so the best way to correct your method would be to switch from using fields to using properties. .NET中的一个好习惯是将数据公开为公共属性,因此,更正方法的最佳方法是从使用字段切换为使用属性。 You'll need to change GetFields to GetProperties (which returns PropertyInfo[] ). 您需要将GetFields更改为GetProperties (返回PropertyInfo[] )。 Then it will work for LINQ to SQL generated classes and for classes that you write like this (using automatic properties in C# 3.0): 然后它将适用于LINQ to SQL生成的类以及您这样编写的类(在C#3.0中使用自动属性):

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

Alternatively, you could use both GetFields and GetProperties , but since a well designed class should not contain public fields, this shouldn't be needed. 另外,您可以同时使用GetFieldsGetProperties ,但是由于设计良好的类不应包含公共字段,因此不需要。

Also, your nested foreach uses GetField in a slightly weird way: 另外,您的嵌套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()); 

For PropertyInfo , this will look the same (you'll only use PropertyInfo instead). 对于PropertyInfo ,外观将相同(您将只使用PropertyInfo )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM