2009-08-31 4 views
3

Я новичок в LINQ, поэтому я довольно запутался здесь. У меня есть база данных и пытаюсь запустить следующий код.LINQ to Entities не распознает метод 'Boolean Contains [Десятичный]

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))) 

На если заявление я получаю ошибку я не понимаю, и я не знаю, как ее решить:

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); 

Однако, почему бы не расширить, где положение:

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

Вы можете заменить .Count() == 0 с помощью Any() –

+1

Может и должен! –

+1

По популярному запросу :-) –

1

Linq 2 SQL не может перевести ids.Contains() для SQL. Вы можете сделать следующее:

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

Это вызовет запрос SQL, поместить их в объекты и сделать содержит локально.

Другим решением было бы поставить conf.umisteni.Budova.Id в ИНЕКЕ (с равными, не содержит), а затем добавить .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 –

+0

Конечно. Идея остается прежней. –

1

Вот вспомогательный метод, который обеспечивает все благости .Contains() в контексте Linq к Entities

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

0

Я только что получил немного что-то подобное. Ваша версия System.Data.dll может быть не такой же. Метод был поддержан на моей машине dev, но затем я получил ошибки времени выполнения, когда я развернулся на тестовой машине. Версия System.Data.dll была старше. Хорошие решения - совместимые с обратной стороной методы. Но я все равно хочу отследить несоответствие, какой-то патч должен применяться, но не в других средах. Кто знает, какие другие проблемы это вызовет по дороге, если их не остановить.

Смежные вопросы