2009-08-31 51 views
3

我是LINQ的新手,所以我很困惑這裏。我有一個數據庫,並嘗試運行以下代碼。LINQ to Entities不識別方法'布爾包含[Decimal]

IQueryable<decimal> location_ids = (from m in _db.Admins 
            where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d") 
            select m.LocationId); 
if (!location_ids.Contains(new Decimal(conf.umisteni.Budova.ID))) 

在if語句我得到一個錯誤,我不明白,我也不知道,如何解決這個問題:

System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean Contains[Decimal](System.Linq.IQueryable`1[System.Decimal], System.Decimal)' method, and this method cannot be translated into a store expression. 
    at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) 

任何想法?

回答

8

使用Linq-to-Objects IEnumerable可讓您對查詢結果使用Contains(Decimal)。

IEnumerable<decimal> location_ids = (from m in _db.Admins 
            where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d") 
            select m.LocationId); 

但是,爲什麼不只是擴大where子句:

IEnumerable<decimal> location_ids = (from m in _db.Admins 
            where m.UserId.Equals("c5d3dc0e-81e6-4d6b-a9c3-faa802e10b7d") && (m.LocationId == conf.umisteni.Budova.ID) 
            select m.LocationId); 
if (!location_ids.Any()) 
+6

您可以用Any()代替.Count()== 0 – 2009-08-31 11:53:15

+1

可以且應該! – 2009-08-31 13:06:54

+1

根據流行的請求:-) – 2009-08-31 13:22:46

1

LINQ的2 SQL無法翻譯ids.Contains()方法爲SQL。 你可以做到以下幾點:

if(!location_ids.ToList().Contains(new Decimal(conf.umisteni.Budova.ID))) 

這將觸發SQL查詢,把他們中的對象,做本地包含的內容。

另一個解決方案是把conf.umisteni.Budova.Id在Where子句(與平等,而不是包含),然後添加.ANY

if((from m in _db.Admins 
    where m.UserId.Equals(conf.umisteni.Budova.ID.ToString()) 
    select m.LocationId).Any()) 

這隻會是一個好主意如果你以後不需要任何鑰匙的話。

+0

你的第二個建議比較UserID和conf.umisteni.Budova.ID,而它應該是LocationId – 2009-08-31 12:02:15

+0

當然。這個想法保持不變。 – 2009-08-31 14:33:19

1

這裏是一個輔助方法,它提供了一個LINQ to實體

public static class LinqToEntitiesUtil 
{ 
    /// <summary> 
    /// Extension method that enables .Contains(obj) like functionality for Linq to Entities. 
    /// 
    /// Source: http://www.velocityreviews.com/forums/t645784-linq-where-clause.html 
    /// </summary> 
    /// <typeparam name="TElement">The element being evaluated by the Where clause</typeparam> 
    /// <typeparam name="TValue">The value to match</typeparam> 
    /// <param name="valueSelector">Lamda for selecting matching values</param> 
    /// <param name="values">IEnumerable of the values</param> 
    /// <returns>Expression consumable by Linq to Entities that reflects semantics of .Contains(value)</returns> 
    /// <remarks> 
    /// Usage: 
    /// 
    /// Replace expression like 
    /// 
    /// where ChildrenIDs.Contains(items.CategoryID) 
    /// 
    /// with 
    /// 
    /// .Where((BuildContainsExpression<Item, int>(item => item.CategoryID, ChildrenIDs)) 
    /// 
    /// NOTE: If the item collection is large, the SQL query will be as well. 
    /// </remarks> 
    static public Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values) 
    { 
     if (null == valueSelector) 
     { 
      throw new ArgumentNullException("valueSelector"); 
     } 
     if (null == values) { throw new ArgumentNullException("values"); } 

     ParameterExpression p = valueSelector.Parameters.Single(); 
     if (!values.Any()) 
     { 
      return e => false; 
     } 

     var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue)))); 
     var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal)); 
     return Expression.Lambda<Func<TElement, bool>>(body, p); 
    } 
} 
+0

+1爲工作解決方案。想知道爲什麼這樣的簡單事情在Entity Framework中很難實現.... – Andomar 2012-12-06 10:02:40

0

我只是類似的東西了位環境中的所有。載有()的善良。您的System.Data.dll可能不是相同的版本。該方法在我的開發機器上得到了支持,但是當我部署到測試機器時,出現運行時錯誤。 System.Data.dll版本較舊。向後兼容的方法是一個很好的解決方法。但是我仍然想要追蹤這種差異,但一些補丁必須應用於其他環境。誰知道如果不加控制,這會導致什麼其他問題。

相關問題