LINQ to Entities не распознает метод «Логическое значение содержит [десятичное число] - PullRequest
3 голосов
/ 31 августа 2009

Я новичок в LINQ, поэтому я довольно запутался здесь. У меня есть база данных, и я пытаюсь запустить следующий код.

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)

Есть идеи?

Ответы [ 4 ]

8 голосов
/ 31 августа 2009

Использование 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())
1 голос
/ 20 сентября 2012

Вот вспомогательный метод, который обеспечивает все преимущества .Contains () в контексте Linq to 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);
    }
}
1 голос
/ 31 августа 2009

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 голосов
/ 27 декабря 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...