是否可以从DataContext.ExecuteQuery返回IEnumerable的匿名对象?

时间:2009-05-14 12:26:28

标签: linq linq-to-sql anonymous-types

我开发了一个报告引擎,其中报告基于模板。每个模板都包含SQL查询字符串,每个报表都有SQL查询参数的特定值。要呈现报告,我设置参数并调用DataContext.ExecuteQuery方法来获取记录列表。但要捕获返回的列,我必须知道它们的名称,并且有一个具有相应属性的类。

是否有可能以某种方式从DataContext.ExecuteQuery返回IEnumerable匿名对象,然后使用Reflection确定它们的属性?

我需要SqlDataReader.GetValues的LINQ等价物。

谢谢!

3 个答案:

答案 0 :(得分:4)

在我们使用带有dynamiс关键字的C#4.0之前,我们可以使用此解决方案(OctavioHernándezLeal撰写的文章Executing arbitrary queries in LINQ to SQL略有修改的代码):

public static class DataContextExtension
{
    public static IEnumerable<Dictionary<string, object>> ExecuteQuery(this DataContext dataContext, string query)
    {
        using (DbCommand command = dataContext.Connection.CreateCommand())
        {
            command.CommandText = query;
            dataContext.Connection.Open();

            using (DbDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
            {
                while (reader.Read())
                {
                    Dictionary<string, object> dictionary = new Dictionary<string, object>();

                    for (int i = 0; i < reader.FieldCount; i++)
                        dictionary.Add(reader.GetName(i), reader.GetValue(i));

                    yield return dictionary;
                }
            }
        }
    }
}

此扩展方法返回字典&lt;&gt;的IEnumerable键是查询列名称的对象。

答案 1 :(得分:0)

是的,你可以做到。 请看一下这个片段。

class Program {
        static void Main(string[] args) {
            var persons = new Person[]{
                new Person{Age=22,Name="John Doe",Id=1},
                new Person{Age=23,Name="Jack Smith", Id=2},
                new Person{Age=34,Name="Sara Parker", Id=3}
            };
            var anonData = GetAnonTypes(persons);
            foreach (var item in anonData as IEnumerable) {
                //use reflection to access propties 
            }
        }
        static object GetAnonTypes(IEnumerable<Person> persons) {
            var query=from p in persons  select new{
                Id=p.Id,
                Name=p.Name
            };
            return query;        
        }
    }

    public class Person {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

答案 2 :(得分:-4)

  • 编译器无法打开您的sql并确定应该存在的属性。
  • 由于您希望编译器这样做,我必须得出结论,您并不真正理解匿名输入。

不要使用LinqToSql。只需使用DataReader方法。