1

我們使用ObservableCollections在我們看來機型相當多,因爲我們使用的是MVVM,並節省一些打字,我決定這將是有轉換一個IEnumerable的擴展方法有用直接向一個ObservableCollection,而不必建立一個新的ObservableCollection各一次。異常試圖擴展方法來創建一個ObservableCollection

這樣,不是打字...

ObservableCollection fred = new ObservableCollection(myCollection); 

...我們可以輸入...

ObservableCollection fred = myCollection.ToObservableCollection(); 

顯然,在人爲的例子上面有小的好處這一點,但在一個更大的Linq查詢中,這可以清理代碼很多。

不管怎麼說,我寫了這樣一個簡單的擴展方法...

public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> collection) { 
    if (collection != null) { 
    return new ObservableCollection<T>(collection); 
    } 
    throw new ArgumentNullException("collection"); 
} 

然而,當我嘗試使用此,我得到一個異常...

LINQ到實體不承認該方法 'System.Collections.ObjectModel.ObservableCollection`1 [VisionRT.CRM.Entities.SiteOverview] ToObservableCollection [SiteOverview](System.Collections.Generic.IEnumerable`1 [VisionRT.CRM.Entities.SiteOverview])' 方法,和該方法不能轉換成商店表達式。

我能明白這一點,如果它是不是事實,ToList()擴展方法不完全一樣的東西,但工程。

任何人,爲什麼我的方法失敗的任何想法,以及如何解決它?謝謝。

回答

0

我認爲問題是,你正在運行你對enrity框架查詢。該查詢實際上在sql服務器上運行。因爲在那裏不支持你的擴展方法(與列表相反),它失敗了。

+0

這就是我想,但如果是這樣,怎麼來的ToList方法的作品?這也是針對EF運行的,也不能轉換成商店方法。 – 2013-03-01 14:26:58

+0

任何人都可以回答這個問題嗎? – 2013-03-05 16:23:15

0

我以前遇到類似的問題(特別是LINQ到實體),一般的解決方案是使用Expression Trees在編譯時建立LINQ,而不是推遲到運行時。

你有沒有嘗試過這樣的:

public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> collection) 
{ 
    var observableCollection = new ObservableCollection<T>(); 

    foreach (var item in collection) 
    { 
     observableCollection.Add(item); 
    } 

    return observableCollection; 
} 

我不知道是否會作出任何差別,但值得一試。

至於omer schleifer's answer

得到實體框架允許擴展方法的一個例子是試圖概括其dbContext.Set<T>綽號。相反,這樣做的:

dbContext.People.Where(p => p.Id == 1234); 

我希望能夠做到這一點:

dbContext.Get<Person>(p => p.Id == 1234); 

這種方法是行不通的:

public static T Get<T>(this DapperDbContext dbContext, int id, string property = "Id") where T : class 
{ 
    return dbContext.Set<T>().FirstOrDefault(t => (int)t.GetType().GetProperty(property).GetValue(t) == id); 
} 

然而,這一個不工作:

public static T Get<T>(this DapperDbContext dbContext, int id, string property = "Id") where T : class 
{ 
    var parameter = Expression.Parameter(typeof(T)); 
    var lambda = Expression.Lambda<Func<T, bool>>(Expression.Equal(Expression.Property(parameter, property) 
     , Expression.Constant(id)), parameter); 
    return dbContext.Set<T>().FirstOrDefault(lambda); 
} 

你也許可以做到事端g類似於您的場景。

希望這會有所幫助。