无法在Entity Framework中执行LINQ复杂对象搜索

时间:2016-10-13 15:38:04

标签: c# sql entity-framework linq

我在数据库中有实体,每个实体都包含一个键值对列表作为元数据。我想通过匹配元数据中的指定项来返回对象列表。

即如果对象可以包含KeyOne,KeyTwo和KeyThree的元数据,我希望能够说出"把我带回KeyOne所包含的所有对象" abc"和KeyThree包含" de"

这是我的C#查询

 var objects = repository.GetObjects().Where(t =>
                    request.SearchFilters.All(f =>
                        t.ObjectChild.Any(tt =>
                            tt.MetaDataPairs.Any(md =>
                                md.Key.ToLower() == f.Key.ToLower() && md.Value.ToLower().Contains(f.Value.ToLower())
                            )
                        )
                    )
                ).ToList();

这是我的请求类

[DataContract]
public class FindObjectRequest
{
    [DataMember]
    public IDictionary<string, string> SearchFilters { get; set; }
}

最后是我的元数据POCO

[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; }
}

我得到的错误是

  

错误无法创建类型的常量值   &#39; System.Collections.Generic.KeyValuePair`2 [[System.String,mscorlib,   版本= 4.0.0.0,文化=中立,   PublicKeyToken = b77a5c561934e089],[System.String,mscorlib,   Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]&#39;。   此处仅支持原始类型或枚举类型   上下文。

1 个答案:

答案 0 :(得分:0)

因此,查询中的.table2, .tabel2 tr, .table2 td {} 变量似乎是f。您需要做的是在使用它们之前将它们保存为局部变量,因为KVP无法转换为SQL。

KeyValuePair<string, string>

你需要记住的是,当你仍然属于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(); 类型时,你在EF中的LINQ中做了什么 - 这是在你致电IQueryable<T>ToList(),{{1甚至可能ToArray()(我老实说从未尝试ToDictionary()) - 必须能够表示为SQL。这意味着只能在AsEnumerable()中定义的SQL类型(字符串,整数,长整数,字节,日期等)和实体类型才能在查询中使用。其他一切都需要分解为其中一种形式。

修改
你也可以试试来自查询的另一面,但你首先需要一些东西..

模特......

AsEnumerable()

现在查询...

DbContext

这应该针对您需要匹配的元对数量执行'n'个SQL查询。更好的选择是尝试以某种方式联合它们,但没有一些代码可以使用它可能是一个任务。

  

作为旁注:我真的不知道你的课程的名字,所以我使用了&gt; &GT;我能解决什么问题。显然[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; } ... } 不是模型的名称..