Невозможно выполнить поиск сложных объектов LINQ в Entity Framework

У меня есть сущности в БД, каждая из которых содержит список o var objects = репозиторий . GetObjects (). Где ( т => запрос . SearchFilters . Все ( е => т . ObjectChild . Любой ( тт => TT . MetaDataPairs . Любой ( мкр => мкр . Ключевые . ToLower () == f . Ключ . ToLower () && md . Значение . ToLower (). Содержит ( f . Значение . ToLower ()) ) ) ) ). ToList (); ключевые пары значений в качестве метаданных. Я хочу вернуть список общедоступного класса [ DataContract ] FindObjectRequest { [ DataMember ] public IDictionary < строка , строка > SearchFilters { get ; набор ; } } путем сопоставления по указанным элементам в метаданных.

Т.е. если объекты могут иметь метаданные KeyOne, KeyTwo и KeyThree, я хочу сказать: «Принесите мне все объекты, где KeyOne содержит« abc », а KeyThree содержит« de »,

Это мой запрос C #

[Table("MetaDataPair")]
    public class DbMetaDataPair : IEntityComparable<DbMetaDataPair>
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long Id { get; set; }

        [Required]
        public string Key { get; set; }

        public string Value { get; set; }
}

и это мой класс запроса

f

И, наконец, мой Metadata POCO

KeyValuePair<string, string>

Ошибка, которую я получаю

Ошибка была неспособна создать постоянное значение типа «System.Collections.Generic.KeyValuePair`2 [[System.String, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089], [System.String, mscorlib, Версия = 4.0.0.0, Культура = нейтральная, PublicKeyToken = b77a5c561934e089]] '. В этом контексте поддерживаются только примитивные типы или типы перечислений.

c#,sql,entity-framework,linq,

1

Ответов: 1


0 принят

Таким образом, похоже, что fпеременная в вашем запросе . Что вам нужно сделать, это сохранить их в качестве локальных переменных, прежде чем использовать их в качестве KVP, нельзя преобразовать в SQL.var filters = request.SearchFilters.Select(kvp => new[] { kvp.Key, kvp.Value }).ToArray(); var objects = repository.GetObjects().Where(t => filters.All(f => t.ObjectChild.Any(tt => tt.MetaDataPairs.Any(md => md.Key.ToLower() == f[0] && md.Value.ToLower().Contains(f[1]) ) ) ) ).ToList();

IQueryable<T>

То , что вы должны помнить, что все , что вы делаете в LINQ в EF , когда он еще типа ToList()- который , прежде чем звонить ToArray(), ToDictionary(), AsEnumerable()и , возможно , даже AsEnumerable()(я честно не пробовал DbContext) - должен быть в состоянии представить в виде SQL. Это означает, что в запросе могут использоваться только типы SQL (строка, int, long, byte, date и т. Д.) И типы сущностей, определенные в вашем . Все остальное нужно разбить на одну из этих форм.[Table("MetaDataPair")] public class DbMetaDataPair : IEntityComparable<DbMetaDataPair> { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long Id { get; set; } [Required] public string Key { get; set; } public string Value { get; set; } // this is the navigation property back up to the ObjectChild public virtual ObjectChild ObjectChild { get;set; } } public ObjectChild { ... public ICollection<MetaDataPair> MetaDataPairs { get; set; } // this is the navigation property back up to the "Object" public virtual Object Object { get; set; } ... }

EDIT:
вы также можете попробовать перейти с другой стороны запроса, но сначала вам понадобятся некоторые вещи.

Модель ...

public IEnumerable<Object> GetObjectsFromRequest(FindObjectRequest request)
{
    foreach(var kvp in request.SearchFilters)
    {
        var key = kvp.Key;
        var value = kvp.Value;

        yield return metaDataRepository.MetaDataPairs
            .Where(md => md.Key.ToLower() == key && md.Value.ToLower().Contains(value))
            .Select(md => md.ObjectChild.Object)
    }
}

Теперь для запроса ...

Object

Это должно выполнить «n» количество SQL-запросов для количества мета-пар, которые нужно сопоставить. Лучший вариант - попытаться объединить их как-то, но без какого-либо кода, чтобы играть с этим, может быть, миссия.

В качестве примечания: я не знаю названия ваших классов, поэтому я использовал>> то, что я могу решить. Очевидно, Objectэто не название модели.

C #, SQL, сущность-рамки, LINQ,