gpt4 book ai didi

c# - 如何使用我自己的方法或为 EF Core 查询编写 DbFunction (EF Core 3.0)

转载 作者:太空宇宙 更新时间:2023-11-03 22:29:56 28 4
gpt4 key购买 nike

我之前有以下设置:

public static bool BlogIsLive(BlogPost b)
{
return b.Status == (int)ItemStatus.Active && b.PublishDate < DateTime.Now ;
}

/// Database query

var blogs = (from b in db.BlogPost
where BlogIsLive(b) // <--- super useful, used in multiple places
select b
).ToList()

但是更新到EF Core 3.0后,抛出如下错误

/// The LINQ expression ... could not be translated. Either rewrite the query in a form 
/// that can be translated, or switch to client evaluation explicitly by inserting a
/// call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().

我知道这是 EF Core 3.0 中重大变化的一部分

现在我必须在 BlogsIsLive() 之前的所有地方手动编写查询。

var blogs = from b in db.BlogPost 
where b.Status == (int)ItemStatus.Active //<--- Annoying repetition of code
&& b.PublishDate < DateTime.Now //<---
select b

这很烦人。有没有办法我可以编写一个插入其中的方法?

我知道 EF 有 DbFunctions,例如,它可以简化比较 Date 值的过程,所以我看不出为什么我不能自己写一些类似的东西Intstringbool

类似于:

public static DbFunction BlogIsLive(BlogPost b)
{
//Example
return DbFunction(b.Status == (int)ItemStatus.Active && b.PublishDate < DateTime.Now);
}

/// Database query

var blogs = (from b in db.BlogPost
where MyDbFunctions.BlogIsLive(b)
select b
).ToList();

我在上面尝试了一些变体,但没有成功。

谢谢。

最佳答案

原始代码有一个严重的错误,该错误也会在任何非核心版本的 EF 中引发 - 它是本地函数,无法转换为 SQL。 Where接受表达式 作为参数,而不是函数。反正你不需要那个功能。

LINQ 使用 IQueryable 和表达式。每个运算符接受一个 IQueryable 并返回另一个。就是这样WhereSelect已经工作了。这意味着您可以创建自己的函数来添加 Where你想要的条件:

public static IQueryable<BlogPost> WhereActive(this IQueryable<BlogPost> query)
{
return query.Where(b=>b.Status == (int)ItemStatus.Active && b.PublishDate < DateTime.Now);
}

并将其与任何 IQueryable<BlogPost> 一起使用,例如:

var finalQuery = query.WhereActive();
var posts=finalQuery.ToList();

另一个更麻烦的选择是构造 Expression<Func<>>调用代码,并将其传递给 Where - 本质上是动态创建 WHERE 条件。在这种情况下,它是不需要的。

EF Core 1.0 添加了一个非常不幸的功能(更像是一种 what-were-they-thinking! 的功能),即客户端评估。如果无法翻译某些内容,只需将所有内容加载到内存中并尝试过滤内容,而无需借助数据库服务器中的索引、执行计划、匹配算法、RAM 和 CPU。

如果一次仅由 1 个客户端加载 100 行,这可能不会被注意到,这对于任何具有少量数据和并发用户的应用程序来说都是性能 killer 。

在 Web 应用程序中,这意味着需要更多的服务器来处理相同的流量。

这就是 2008 年引入 EF 1.0 时删除客户端计算的原因。

关于c# - 如何使用我自己的方法或为 EF Core 查询编写 DbFunction (EF Core 3.0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58428949/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com