2015-02-11 20 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

相關問題