LINQ:为什么我不能在返回的对象中声明新对象?

时间:2012-04-06 22:16:15

标签: c# linq entity-framework-4 properties

首先,我做了一些寻找这个问题的答案...但我找不到任何原因,因为我不知道我正在使用的功能是什么。

以下代码中的DBEntities是由devart为Oracle DB连接生成的。

为什么第一个示例有效,第二个示例只给我一个System.NullReferenceException?

有效代码:

using (DBEntities context = new DBEntities())
{
    var infos = (from info in context.Infos
                 where info.Index == index
                 orderby info.Name
                 select new
                 {
                     Name = info.Name,
                     MRN = info.MRN,
                     UnitNumber = (info.UnitNum == null) ? -1 : (decimal)info.UnitNum,
                     UnitName = (info.UnitName == null) ? String.Empty : info.UnitName
                 }).Distinct();

    foreach (var info in infos)
    {
        // *do stuff*
    }
}

提供异常的代码(只有在到达foreach时才会看到异常):

using (DBEntities context = new DBEntities())
{
    var infos = (from info in context.Infos
                 where info.Index == index
                 orderby info.Name
                 select new Member()
                 {
                     Name = info.Name,
                     MRN = info.MRN,
                     CurrentUnit = new Unit()
                     {
                         UnitNumber = (info.UnitNum == null) ? -1 : (decimal)info.UnitNum,
                         UnitName = (info.UnitName == null) ? String.Empty : info.UnitName
                     }
                 }).Distinct();

    foreach (Member info in infos)
    {
        // *do stuff*
    }
}

修改 我想补充一点,这也有效:

using (DBEntities context = new DBEntities())
{
    var infos = (from info in context.Infos
                 where info.Index == index
                 orderby info.Name
                 select new Member()
                 {
                     Name = info.Name,
                     MRN = info.MRN
                 }).Distinct();

    foreach (Member info in infos) //Exception is thrown here.
    {
        // *do stuff*
    }
}

2 个答案:

答案 0 :(得分:2)

第一个可行,因为您可以从SQL返回这些匿名类型,EF可以为整个表达式生成SQL语句。第二个不是因为您无法在SQL中创建Member类的实例。如果强制进行枚举(使用AsEnumerable()),则可以创建成员值客户端。

在枚举时总会抛出异常,因为LINQ在设计上完全是“懒惰的”。如果你想在创建表达式的时候强制它发生(比如说测试目的),那么在它的末尾添加.ToList()

答案 1 :(得分:0)

而不是

foreach (Member info in infos) //Exception is thrown here.
{
    // *do stuff*
}

使用

foreach (var info in infos) //Valid.
{
    // *do stuff*
}

这是因为infos会返回anonymus结果。这不是完全Member集合类。

相关问题