2011-04-23 118 views
1

使用下面的代碼(簡體),我得到的錯誤實體框架4.1:庫與「DefaultOrder屬性」

「無法轉換類型‘System.DateTime的’輸入‘System.Object的’。 LINQ to Entities只支持投射實體數據模型原語類型。「

與return語句行

public MyRepository<Post> 
{ 
    public Expression<Func<Post, object>> DefaultOrder; 

    public MyRepository() 
    { 
    DefaultOrder = p => p.PublishedOn; 
    } 

    public IQueryable<Post> All() 
    { 
    var entities = new MyDbContext().Set<Post>(); 
    return entities.OrderByDescending(DefaultOrder); 
    } 
} 

我使用相同的代碼使用db4o,而不是實體框架/ db4o.Linq也沒有問題。

所以在這裏我的問題:

  1. 爲什麼這個錯誤發生?
  2. 有沒有其他的解決方案,它可以讓我像現在一樣(類似)地定義我的DefaultOrder?

編輯:

發現一個溶液,爲我的作品,用命令的方法替換了默認順序表達:

public MyRepository<T> 
{ 
    public Func<IQueryable<T>, IOrderedQueryable<T>> DefaultOrderMethod; 

    public MyRepository() 
    { 
    DefaultOrderMethod = o => o.OrderBy(x => x.PublishedOn); 
    } 

    public IQueryable<T> All() 
    { 
    var entities = new MyDbContext().Set<T>(); 
    return DefaultOrderMethod(entities); 
    } 
} 
+0

您是否嘗試事先進行鑄造? ('DefaultOrder = p =>(object)p.PublishedOn;') – AbdouMoumen 2011-04-23 19:29:21

+0

好主意! - 但不幸的是不工作... – davehauser 2011-04-23 19:40:33

回答

1

第二種類型傳遞到表達OrderBy擴展方法是從表達式返回的類型推斷出來的。它期待一個Expression>。所以如果你要存儲排序表達式,你需要明確地給它一個TOrderBy類型。

public MyRepository<Post> 
{ 
    public Expression<Func<Post, DateTime>> DefaultOrder; 

    public MyRepository() 
    { 
    DefaultOrder = p => p.PublishedOn; 
    } 

    public IQueryable<Post> All() 
    { 
    var entities = new MyDbContext().Set<Post>(); 
    return entities.OrderByDescending(DefaultOrder); 
    } 
} 

.NET不支持拳擊/除非你通過協方差和逆變這不會對你的工作,例如使用.NET 4.0和使用接口拆箱泛型參數類型。

這就是泛型系統在.NET中的工作原理。唯一的原因,像這樣的作品...

Query.OrderBy(x => x.PublishedOn)

...是因爲TOrderBy類型可以從表達式返回類型(日期時間)來推斷。

+0

感謝您的解釋。雖然我寫了相同的代碼,但是當我使用[db4o](http://db4o.com)時使用了相同的代碼。有任何想法嗎? – davehauser 2011-04-23 19:36:23

+0

你有一個好主意如何以不同的方式實現這個功能? – davehauser 2011-04-23 19:38:08

+0

你可以做很多不同的方式,但我懷疑你將能夠實現你期望的最終結果,這只是.NET的限制。 – 2011-04-23 20:51:53