2012-02-17 49 views
4

這是基於一個名爲Task一個波科類一個簡單的項目:包括衍生財產爲LINQ到實體查詢

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (MyDbContext ctx = new MyDbContext()) 
     { 
      // first query 
      DateTime compareDate = DateTime.Now + TimeSpan.FromDays(3); 
      var res = ctx.Tasks.Where(t => t.LastUpdate < compareDate).ToList(); 

      // second query 
      res = ctx.Tasks.Where(t => t.ShouldUpdate).ToList(); 
     } 
    } 
} 

public class MyDbContext : DbContext 
{ 
    public DbSet<Task> Tasks { get; set; } 
} 

public class Task 
{ 
    public int ID { get; set; } 
    public DateTime LastUpdate { get; set; } 
    public bool ShouldUpdate 
    { 
     get 
     { 
      return LastUpdate < DateTime.Now + TimeSpan.FromDays(3); 
     } 
    } 
} 

我想要做的是查詢上下文dbset包括where子句的ShouldUpdate在派生財產。

「第一個查詢工作正常」(我不能寫在一行中,但它並不重要)。如您所知,我們在「第二個查詢」上得到一個NotSupportedException,並帶有以下消息: LINQ to Entities不支持指定的類型成員'ShouldUpdate'。僅支持初始化程序,實體成員和實體導航屬性。

這是正確的,我可以理解爲什麼會發生這種情況,但我需要將派生的信息封裝在Task對象中,以便我可以在網格中顯示屬性或在其他位置使用它,而不重複其背後的邏輯。

有沒有一個聰明的技術來做到這一點?

注意:ShouldUplate屬性的技術名稱是什麼?得到的?如何計算?計算的?

回答

3

最後我找到了解決辦法.. 您可以將部分查詢(表達式)存儲在靜態的Fileds並使用它們像這樣:

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (MyDbContext ctx = new MyDbContext()) 
     { 
      res = ctx.Tasks.Where(Task.ShouldUpdateExpression).ToList(); 
     } 
    } 
} 

public class MyDbContext : DbContext 
{ 
    public DbSet<Task> Tasks { get; set; } 
} 

public class Task 
{ 
    public int ID { get; set; } 
    public DateTime LastUpdate { get; set; } 
    public bool ShouldUpdate 
    { 
     get 
     { 
      return ShouldUpdateExpression.Compile()(this); 
     } 
    } 

    public static Expression<Func<Task, bool>> ShouldUpdateExpression 
    { 
     get 
     { 
      return t => t.LastUpdate < EntityFunctions.AddDays(DateTime.Now, 3); 
     } 
    } 
} 
+0

我有一個類似的問題,但即使當我嘗試使用上面的靜態表達式時,我也會收到「不支持」的錯誤。任何想法爲什麼這可能是? – MysteriousWhisper 2014-04-29 16:37:15

+0

你能舉個例子嗎? – 2014-06-06 09:35:15

0

您需要將ShouldUpdate邏輯放入linq-to-enitites查詢中。您可以使用EntityFunctions.AddDays來幫助你,像這樣

res = ctx.Tasks.Where(t => t.LastUpdate < EntityFunctions.AddDays(DateTime.Now, 3)).ToList(); 
1

庫模式將提供在這種情況下,更好的抽象。您可以按如下方式集中邏輯。在你的上下文中定義一個新的屬性TaskSource

public class MyDbContext : DbContext 
{ 
    public DbSet<Task> Tasks { get; set; } 

    public IQueryable<Task> TaskSource 
    { 
     get 
     { 
      return Tasks.Where(t => t.LastUpdate < EntityFunctions.AddDays(DateTime.Now, 3)); 
     } 
    } 
} 
+0

所以..你說的數據模型對象不應該根本不包含任何邏輯? – 2012-02-21 09:24:31

+0

@ user846168實體可以包含邏輯。放置這種類型邏輯的適當位置取決於上下文。 – Eranga 2012-02-21 09:35:33