我们在视图模型中使用ObservableCollections,因为我们正在使用MVVM,为了节省一些输入,我认为有一个扩展方法将IEnumerable直接转换为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 to Entities无法识别方法'System.Collections.ObjectModel.ObservableCollection`1 [VisionRT.CRM.Entities.SiteOverview] ToObservableCollection [SiteOverview](System.Collections.Generic.IEnumerable`1 [VisionRT.CRM.Entities .SiteOverview])'方法,此方法无法转换为商店表达式。
如果不是因为ToList()扩展方法完全相同的事情,我会理解这一点,但是有效。
任何想法为什么我的方法失败,以及如何解决它?感谢。
答案 0 :(得分:0)
我认为问题在于您是在针对enrity框架运行查询。该查询实际上是在sql server上运行的。因为那里没有对你的扩展方法的支持(与列表相反),它失败了。
答案 1 :(得分:0)
我过去遇到过类似的问题(尤其是LINQ-to-Entities),一般的解决方案是使用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;
}
我不知道这是否会产生任何影响,但值得一试。
获取实体框架以允许扩展方法的一个示例是尝试概括其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);
}
您可以为您的方案做类似的事情。
希望这有帮助。