2012-01-05 94 views
0

以下Linq to Entities查询正在导致“无法创建类型为'Data.InhouseUnit'的常量值,只有原始类型(如Int32,String和Guid' )在此上下文中被支持“异常。Linq中的if-else子句转为实体框架查询

IList<FaultReport> faultReports = (from fr in _session.FaultReports 
    where fr.CreatedOn > dateTime 
    select new FaultReport 
    { 
     Id = fr.Id, 
     ExecutionDate = fr.ExecutionDate ?? DateTime.MinValue, 
     FaultType = fr.FaultType, 
     Quarters = fr.Quarters, 
     InhouseSpaceId = fr.InhouseSpaceId, 
     InhouseSpace = new InhouseSpace { Id = fr.InhouseSpace.Id, Name = fr.InhouseSpace.Name }, 
     InhouseUnitId = fr.InhouseUnitId ?? Guid.Empty, 
     **InhouseUnit = fr.InhouseUnitId == Guid.Empty ? null : new InhouseUnit { Id = fr.InhouseUnit.Id, Name = fr.InhouseUnit.Name }** 
}).ToList(); 

具体而言,它是以粗体字体引起异常的if表达式。我需要将检查作为fr.InhouseUnitId是可以为空的。如果我拿出粗体的表达,那么声明的其余部分工作得很好。我花了相当长的时间,在msdn论坛和网络上,了解是什么导致异常,但仍然不能理解。 Guid是标量,所以它应该工作,对吧?即使这个表达式InhouseUnit = true ? null: new InhouseUnit()代替上述语句中的粗体表达也是行不通的。如果/其他

,如果我尝试写一个扩展方法来带走的逻辑,只是返回结果,以下异常被抛出可以,我们甚至写:

LINQ to Entities does not recognize the method 'System.Object 
GuidConversion(System.Nullable`1[System.Guid], System.Object)' method, and this method 
cannot be translated into a store expression 
+1

如果我没看错,这里的问题是,编译器不能编译LINQ到SQL查询,因为它不知道fr.InhouseUnitId什么样的价值 - Guid.Empty将在那个时候。 LINQ语句必须是常量才能编译成SQL语句。 因为我不知道这个解决方案,所以我把它留作评论。 – 2012-01-05 00:10:26

+0

@DarylTeo,编译很好,异常在运行时被抛出。最初我的支票是fr.InhouseUnitId == null,因为fr.InhouseUnitId是可以为空的。我之前在LINQtoSQL中使用过这样的表达式,没有任何问题。实体框架可能会做一些奇怪的事情。 – Xience 2012-01-05 09:45:10

回答

0

它看起来像你伸入新您正在查询的相同类型的对象。是这样吗?这看起来有点不可思议,但假设你有这样做的充分理由,你可以将查询分成两部分。第一部分将从数据库中获得你所需要的。第二部分将在本地运行(即LINQ到对象),以便为您提供所需的投影。事情是这样的:

var query = 
    from fr in _session.FaultReports 
    where fr.CreatedOn > dateTime 
    select new { 
    fr.Id, 
    fr.ExecutionDate, 
    fr.FaultType, 
    fr.Quarters, 
    InhouseSpaceId = fr.InhouseSpace.Id, 
    InhouseSpaceName = fr.InhouseSpace.Name, 
    InhouseUnitId = fr.InhouseUnit.Id, 
    InhouseUnitName = fr.InhouseUnit.Name, 
    }; 

IList<FaultReport> faultReports = (
    from fr in query.ToList() 
    select new FaultReport { 
    Id = fr.Id, 
    ExecutionDate = fr.ExecutionDate ?? DateTime.MinValue, 
    FaultType = fr.FaultType, 
    Quarters = fr.Quarters, 
    InhouseSpaceId = fr.InhouseSpaceId, 
    InhouseSpace = new InhouseSpace { Id = fr.InhouseSpaceId, Name = fr.InhouseSpaceName }, 
    InhouseUnitId = fr.InhouseUnitId ?? Guid.Empty, 
    InhouseUnit = fr.InhouseUnitId == Guid.Empty ? null : new InhouseUnit { Id = fr.InhouseUnitId, Name = fr.InhouseUnitName } 
    }).ToList();