基于每个实体中的字典过滤 C# 中的查询

问题描述 投票:0回答:1

我有一个来自数据库的查询,我想根据表“ExtraProperties”中的列来过滤查询,该表在 Sql 中以 json 格式编写,但在获取查询时,它会映射到字典,这是查询,这就是我尝试做的:

        var query = await repository.GetQueryableAsync();
        query = query.Where(i => (bool)EF.Property<Dictionary<string, object?>>(i, "ExtraProperties")["AutoGenerated"] == true);

“ExtraPorperties”是属性,“AutoGenerate”是字典上的键,我知道该值的类型是“bool”。 但是这段代码给了我一个错误,说“Linq 查询无法翻译”,所以我的问题是,是否有其他方法可以根据键值字典“ExtraProperties”过滤记录?

请注意,该方法是通用的,C# 无法识别查询内实体内的任何属性。

c# asp.net linq
1个回答
0
投票

鉴于

ExtraProperties
是一个 JSON 字符串,您可以尝试进行扩展以将字符串转换为内联字典,并在值上使用
Convert

static partial class Extensions
{
    public static Dictionary<string, string> ToDict(this string json) =>
        JsonConvert
        .DeserializeObject<Dictionary<string, string>>(json ?? string.Empty)
        ?? new Dictionary<string, string>();
}

你可以这样使用它:

query = query
    .Where(record => 
        Convert
        .ToBoolean(record.ExtraProperties.ToDict()["AutoGenerated"]))
        .ToList();

这是我用来测试这个答案的控制台模拟。

using Newtonsoft.Json;

Console.Title = "Test ToDict() Extension";
var query =
    Enumerable.Range(0, 10)
    .Select(n => new MockItem{Id = n, })
    .ToList();

Console.WriteLine($"Total item count = {query.Count}");

query = query
    .Where(record => Convert.ToBoolean(record.ExtraProperties.ToDict()["AutoGenerated"]))
    .ToList();

Console.WriteLine($"Reduced item count = {query.Count}");
Console.WriteLine(string.Join(Environment.NewLine, query.Select(record=>record.ToString())));
Console.ReadLine();


class MockItem
{
    static Random _rando = new Random(1);
    public  MockItem() 
    {
        // Generate random T/F for property and
        // save as json formatted string.
        ExtraProperties = JsonConvert.SerializeObject(
            new Dictionary<string, object>
            {
                { "AutoGenerated", _rando.Next(2).Equals(1) },
            });
    }

    public int Id { get; set; }
    public string ExtraProperties { get; }
    public override string ToString() =>
        $"{Id} ExtraProperties = {ExtraProperties}";
}

static partial class Extensions
{
    public static Dictionary<string, string> ToDict(this string json) =>
        JsonConvert
        .DeserializeObject<Dictionary<string, string>>(json ?? string.Empty)
        ?? new Dictionary<string, string>();
}
© www.soinside.com 2019 - 2024. All rights reserved.