2015-02-11 19 views
0

我有这两款机型与一对多的关系:“方法不能被翻译成店表达”怪异的行为

[Table("User")] 
public class User 
{ 
    public User() 
    { 
     Times = new HashSet<Time>(); 
    } 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public Guid Guid { get; set; } 

    public virtual ICollection<Time> Times { get; set; } 
} 

[Table("Time")] 
public class Time 
{ 
    [Key] 
    public long TimeId { get; set; } 
    public DateTime WorkDay { get; set; } 
    public Guid UserGuid { get; set; } 
    public virtual User User { get; set; } 
} 

和方法在上下文类返回的DataTable。 先执行失败的查询经过.ToDataTable()扩展(或.ToList()或其他) 有异常后:

LINQ to Entities does not recognize the method 'System.String ToShortDateString()' method, and this method cannot be translated into a store expression 

第二个顺利完美的罚款。 问题是为什么?

第一次执行。它不起作用

public DataTable GetDtProjectsForUser(User user) 
{ 
    var query = from time in Time 
       select new 
       { 
        WorkDay = time.WorkDay.ToShortDateString(), 
       }; 
    return query.ToDataTable(); 
} 

第二个。它工作

public DataTable GetDtProjectsForUser(User user) 
{ 
    var localUser = User.Find(user.Guid); 
    var query = from time in localUser.Times 
       select new 
       { 
        WorkDay = time.WorkDay.ToShortDateString(), 
       }; 
    return query.ToDataTable(); 
} 

回答

2

Rohit的答案或多或少是正确的,但他在评论中的解释是错误的。

localUser.Times是(推测)是ICollection<Time>。构建ICollection需要枚举结果集。一旦引用集合,查询就会执行。您的查询等效于:

var collection = localUser.Times.Select(t => new { WorkDay = t.WorkDay.ToShortDateString() }); 

由于作为localUser.Times执行很快,一查询时进行数据库和Times收集被加载。后续的.Select()是一个LINQ to Objects查询。

0

Linq是延期执行。在第一个代码中,时间变量不存储在内存中,而在第二个代码中,您已将该集合存储在localUser变量中。
您可以在Charlie Calvert's Community Blog上阅读关于linq和延期执行的更多信息。

+0

是的,我知道延期执行。但在这两种情况下,“查询”在我调用ToDataTable扩展时执行(至少我是这么认为的)。 – Szer 2015-02-11 06:40:31

+0

@Szer,是的。这是推迟的意思。这两个查询在您调用ToDataTable方法时执行。但是linq执行不像正常执行。为了更好地理解linq,也更喜欢[LINQ如何在内部工作](http://stackoverflow.com/questions/671235/how-linq-works-internally) – 2015-02-11 06:43:45

相关问题