gpt4 book ai didi

c# - EF核心3铸件无法翻译

转载 作者:行者123 更新时间:2023-12-02 13:01:23 25 4
gpt4 key购买 nike

我想将 IQueryable 转换为这样的接口(interface):

public static IQueryable<T> _enableFilter<T>(this IQueryable<T> queryable) => queryable.Where(x => (x as IEnable).Enable);
_newsRepository.BaseQuery.EnableFilter().FirstOrDefaultAsync(x => x.Id == model.Id);

它在 EF core 2.2 上工作,但在 3 中我给出了这个错误:

System.InvalidOperationException : The LINQ expression 'Where<News>(
source: DbSet<News>,
predicate: (n) => (n as IEnable).Enable)' 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(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

最佳答案

此查询在 EF Core 2.2 中也不起作用。该强制转换在 SQL 中没有任何意义 - SQL 中没有接口(interface)或继承。 3 之前的 EF Core 有一个......不幸的功能,客户端评估。如果 EF Core 无法将某些内容转换为 SQL,它会将所有内容提取到客户端并尝试在那里过滤数据。不用说,这对于性能来说是灾难性的。更糟糕的是,它在没有任何警告的情况下就这样做了。警告或异常可以让您识别并解决问题。至少,在 EF Core 2.2 中可以禁用客户端评估。在 EF Core 3 中,这种情况永远消失了。

对于方法本身,如果您使用类型约束,则根本不需要该转换,例如:

public static IQueryable<T> _enableFilter<T>(this IQueryable<T> queryable) 
where T:IEnable
{
return queryable.Where(x => (x as IEnable).Enable);
}

我不确定 EF Core 是否会接受这一点 - 这是不寻常的语法。添加额外条件要容易得多,例如:

_newsRepository.BaseQuery.EnableFilter().FirstOrDefaultAsync(x => x.Id == model.Id && x.Enabled);

全局查询和软删除

如果您想对使用特定实体的所有查询应用过滤条件,例如实现软删除,您可以使用 global filters 。事实上,软删除是文档中提到的第一个场景。

在上下文的 OnModelCreating() 方法中,您可以添加:

modelBuilder.Entity<SomeEntity>().HasQueryFilter(p => p.IsEnabled);

关于c# - EF核心3铸件无法翻译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58326715/

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