【问题标题】:Avoid client evaluation while maintain clean code in EF Core 3避免客户端评估,同时在 EF Core 3 中保持干净的代码
【发布时间】:2020-05-16 15:14:54
【问题描述】:

我需要向我的数据库编写更复杂的查询。 在启用客户端评估的情况下很容易保持干净的代码,但我正在处理大量数据并且需要保持我的后端快速。

客户实体就是一个很好的例子。这就是我的查询现在的样子:

public class CustomerFilter : AbstractProjectFilter
{
    public CustomerFilter(string query, bool includeNotSet, ICollection<string> customers) :
        base(e => (customers == null)
                  || (includeNotSet && e.Customer == null)
                  || (customers.Contains("Company") && e.Customer.Type == CustomerType.Company &&
                      EF.Functions.Like((((CustomerCompany)e.Customer).Name + " " + ((CustomerCompany)e.Customer).Crn + " " + ((CustomerCompany)e.Customer).VatRegNo), "%" + query + "%"))
                  || (customers.Contains("Person") && e.Customer.Type == CustomerType.Person &&
                      EF.Functions.Like(((CustomerPerson)e.Customer).Forename + " " + ((CustomerPerson)e.Customer).Surname, "%" + query + "%"))
                  || (customers.Contains("Evidence") && e.Customer.Type == CustomerType.InEvidence &&
                      EF.Functions.Like(e.Customer.EvidenceName, "%" + query + "%"))
        )
    {
    }
}

启用客户端评估后,这会更简洁,因为我可以使用这种方法来创建基于客户派生类型的名称字符串,并使用扩展方法(我故意避免使用虚拟方法),并使用它来制作我的查询简短而干净:

public static string NameString(this Customer customer)
    {
        if (customer.IsObjectNull())
            return string.Empty;

        return customer.Type switch
        {
            CustomerType.InEvidence => ((CustomerInEvidence) customer).EvidenceName,
            CustomerType.Person => (((CustomerPerson) customer).Forename + " " +
                                    ((CustomerPerson) customer).Surname),
            CustomerType.Company => ((CustomerCompany) customer).Name,
            _ => throw new ArgumentOutOfRangeException()
        };
    }

我的问题:有没有办法告诉数据库如何处理方法而不需要从中获取数据?我缺少一些 Fluent API 的配置?

如果我能像这样在使用 Linq.Dynamic 进行排序时使用这些“方法”,那就太好了:

var orderedCustomers = await customers.OrderBy("*string_created_by_some_method* ASC").ToListAsync();

【问题讨论】:

    标签: c# linq entity-framework-core


    【解决方案1】:

    有没有办法告诉数据库如何处理方法而不需要从中获取数据?我缺少一些 Fluent API 的配置?

    没有什么直截了当的方法,Expression就是这样!

    在不获取数据的情况下与数据库通信的唯一方法是使用Expressions。它不是很直,但可以做你需要的一切。

    你可以看到它的一个例子here

    【讨论】:

    • 天哪,实际上使用 Expression 非常简单。不知道为什么我没有自己想出它。谢谢!
    猜你喜欢
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    相关资源
    最近更新 更多