将方法转换为存储表达式

本文关键字:存储 表达式 转换 方法 | 更新日期: 2023-09-27 18:14:48

我只是想让我的代码和linq查询看起来更好,并为我的银行实体做了一个扩展方法,因为我想让查询看起来像这样

db.Banks.Where(x => x.SomeBooleanParam).Select(x => x.ToSummary())

但是我遇到了异常

Linq-to-Entities不能识别'X.X.Summary ToSummary(X.X.Models.Bank)'方法,并且此方法不能转换为存储表达式。

我的问题:是否有可能以某种方式修改我的ToSummary()函数,所以有可能在查询实体上使用它?我已经提供了如何我的数据库看起来像JSON格式,如何简单的选择看起来像和如何总结看起来像。我读过,该函数必须返回类似Expression<Func<somethingHere, bool>>的东西,但我从来没有理解过它..

//How it looks in the DB
Items: [
    {Id: 1, Name: "Item1"},
    {Id: 2, Name: "Item2"},
    {Id: 3, Name: "Item3"}
]
Banks: [
    {Id: 1, Name: Bank1, SomeBooleanParam: true}
]
BankChanges: [
    {Id: 1, BankId: 1},
    {Id: 2, BankId: 1}
]
BankItems: [
    {Id: 1, ItemId: 1, BankChangeId: 1, Added: 10, Generated: 0},
    {Id: 2, ItemId: 2, BankChangeId: 1, Added: 1, Generated: 1}
    {Id: 3, ItemId: 1, BankChangeId: 2, Added: -10, Generated: 0},
    {Id: 4, ItemId: 2, BankChangeId: 2, Added: 3, Generated: 0},
    {Id: 5, ItemId: 3, BankChangeId: 2, Added: 7, Generated: 0}
]
// How simple select looks like, by including everything
simpleSelect:
[{
    Id: 1,
    Name: Bank1,
    BankChanges: [
        {
            Id: 1,
            BankItems: [
                {
                    Id: 1,
                    Item: {Id: 1, Name: "Item1"},
                    BankChangeId: 1,
                    Added: 10,
                    Generated: 0
                },
                {
                    Id: 2,
                    Item: {Id: 2, Name: "Item2"},
                    BankChangeId: 1,
                    Added: 1,
                    Generated: 1
                }
            ]
        },
        {
            Id: 2,
            BankItems: [
                {
                    Id: 3,
                    Item: {Id: 1, Name: "Item1"},
                    Added: -10,
                    Generated: 0
                },
                {
                    Id: 4,
                    Item: {Id: 2, Name: "Item2"},
                    Added: 3,
                    Generated: 0
                },
                {
                    Id: 5,
                    Item: {Id: 3, Name: "Item3"},
                    Added: 7,
                    Generated: 0
                }
            ]
        }
    ]
}]
// How summary looks like
summary:
[{
    Id: 1,
    Name: Bank1,
    ItemSummaries: [
        // Note: No Item1, because total of Item1 = 0 or less
        {
            Item: "Item2",
            TotalAdded: 4,
            TotalGenerated: 1,
            Total: 5
        },
        {
            Item: "Item3",
            TotalAdded: 7,
            TotalGenerated: 0,
            Total: 7
        }
    ]
}]
public static class BankExtensions {
    public static Summary ToSummary(this Bank bank)
    {
        return new Summary 
        {
            Id = bank.Id,
            Name = bank.Name,
            ItemSummaries = bank.BankChanges
                                .SelectMany(x => x.BankItems)
                                .GroupBy(x => x.Item)
                                .Select(x => new ItemSummary
                                {
                                    Item = x.Key.Name,
                                    TotalAdded = x.Sum(y => y.Added),
                                    TotalGenerated = x.Sum(y => y.Generated),
                                    Total = x.Sum(y => y.Added) + x.Sum(y => y.Generated)
                                })
                                .Where(x => x.Total > 0)
        };
    }
}

将方法转换为存储表达式

类似于

public static class BankExtensions
{
    public static IQueryable<Summary> ToSummary(this IQueryable<Bank> b)
    {
        return b.Select(bank => new Summary
            {
                Id = bank.Id,
                Name = bank.Name,
                ItemSummaries = bank.BankChanges
                                    .SelectMany(x => x.BankItems)
                                    .GroupBy(x => x.Item)
                                    .Select(x => new ItemSummary
                                    {
                                        Item = x.Key.Name,
                                        TotalAdded = x.Sum(y => y.Added),
                                        TotalGenerated = x.Sum(y => y.Generated),
                                        Total = x.Sum(y => y.Added) + x.Sum(y => y.Generated)
                                    })
                                    .Where(x => x.Total > 0)
            }
        );
    }
}

然后像这样使用

db.Banks.Where(x => x.SomeBooleanParam).ToSummary()