3

我首先使用 EF6 代码,我使用这个答案List<stirng>在我的实体中映射 a 。

这是我的课

    [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”。仅支持初始化程序、实体成员和实体导航属性。

什么是合乎逻辑的。

有没有办法执行这样的查询?

4

2 回答 2

3

这里的问题是 LINQ to Entities 不了解如何将您的查询转换为后端 (SQL) 语言。因为您在过滤查询结果之前不会具体化(即转换为 .NET)查询结果,因此 LINQ 会尝试将您的查询转换为 SQL 本身。由于不确定如何执行此操作,因此您会得到一个NotSupportedException.

如果您首先实现查询(即调用 a .ToList())然后进行过滤,则一切正常。不过,我怀疑这不是您想要的。(即db.CategoriaAccesorios.ToList().Where(c => c.ListaEspecifica.Contains("Buc")).First();

正如这个答案所解释的,您的问题是 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
于 2018-10-23T15:57:11.870 回答
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); }
}

我希望有更好/更漂亮的解决方案;)

于 2018-10-23T15:58:06.723 回答