我首先使用EF6代码,我用this的答案在我的整个身体中映射了List<stirng>
。
这是我的课程
[Key]
public string SubRubro { get; set; }
[Column]
private string SubrubrosAbarcados
{
get
{
return ListaEspecifica == null || !ListaEspecifica.Any() ? null : JsonConvert.SerializeObject(ListaEspecifica);
}
set
{
if (string.IsNullOrWhiteSpace(value))
ListaEspecifica.Clear();
else
ListaEspecifica = JsonConvert.DeserializeObject<List<string>>(value);
}
}
[NotMapped]
public List<string> ListaEspecifica { get; set; } = new List<string>();
它非常适合以Json的身份存储我的列表,但是现在我需要执行linq查询,而我正在尝试这样做
var c = db.CategoriaAccesorios.Where(c => c.ListaEspecifica.Contains("Buc")).First();
它正在扔
System.NotSupportedException :指定的类型成员 LINQ to Entities不支持“ ListaEspecifica”。只要 初始化程序,实体成员和实体导航属性是 支持。
什么是合乎逻辑的。
有没有办法执行这样的查询?
答案 0 :(得分:2)
这里的问题是LINQ to Entities无法理解如何将查询转换为后端(SQL)语言。因为您没有实现查询直到的结果(即转换为.NET),所以您对其进行过滤,因此LINQ尝试将查询转换为SQL本身。由于不确定如何执行此操作,因此您会得到NotSupportedException
。
如果首先实现查询(即调用.ToList()
),然后进行过滤,则一切正常。我怀疑这不是您想要的。 (即db.CategoriaAccesorios.ToList().Where(c => c.ListaEspecifica.Contains("Buc")).First();
)
正如this answer所述,您的问题是EF到SQL的转换。显然,您需要某种解决方法。
因为您要进行JSON序列化,所以实际上这里有几个选项,尤其是使用LIKE
:
var c =
(from category
in db.CategoriaAccessorios
where SqlMethods.Like(c.SubrubrosAbarcados, "%\"Buc\"%")
select category).First()
如果是EF Core,则据称Microsoft.EntityFrameworkCore.EF.Functions.Like
应该替换SqlMethods.Like
。
如果您拥有SQL Server 2016+,并且将SubrubrosAbarcados
强制为JSON类型,则应该可以使用原始查询直接直接查询JSON列。
如果您对上述方面感到好奇,请查看以下示例,了解它在SQL Server 2016中的外观:
CREATE TABLE Test (JsonData NVARCHAR(MAX))
INSERT INTO Test (JsonData) VALUES ('["Test"]'), ('["Something"]')
SELECT * FROM Test CROSS APPLY OPENJSON(JsonData, '$') WITH (Value VARCHAR(100) '$') AS n WHERE n.Value = 'Test'
DROP TABLE Test
答案 1 :(得分:1)
我能够通过CompiledExpression做这样的事情。
using Microsoft.Linq.Translations;
// (...) namespace, class, etc
private static readonly CompiledExpression<MyClass, List<string>> _myExpression = DefaultTranslationOf<MyClass>
.Property(x => x.MyProperty)
.Is(x => new List<string>());
[NotMapped]
public List<string> MyProperty
{
get { return _myExpression.Evaluate(this); }
}
我希望有更好/更漂亮的解决方案;)