我需要向数据库中写入更复杂的查询。 很容易在启用客户端评估的情况下保持干净的代码,但是我正在处理大量数据,因此需要保持后端快速。
客户实体就是很好的例子。这就是我的查询现在的样子:
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();
是否有一种方法可以告诉数据库如何处理方法而无需从数据库中获取数据?我缺少一些Fluent API的配置?
没有任何简单的方法,这正是Expression
的含义!
您无需获取数据即可与数据库对话的唯一方法是使用Expressions
。它不是很直,但是可以满足您的所有需求。
您可以看到它的一个示例here