我正在嘗試將軟洗掉改造為使用 EF Core 的 ASP.NET Core 5.0 應用程式。
在 的OnModelCreating方法中是這樣完成的DbContext:
builder.Entity<MyEntity>().Property<bool>("IsDeleted");
builder.Entity<MyEntity>().HasQueryFilter(m => EF.Property<bool>(m, "IsDeleted") == false);
這是在docs 中推薦的。更改底層資料庫物體(如MyEntity)是我想避免的。
像這樣的代碼拋出例外,它曾經完美地作業:
var myEntities= _context.MyEntities.AsNoTracking();
return _mapper.Map<IEnumerable<MyEntity>>(myEntities);
導致(在第二行):
InvalidOperationException: The LINQ expression 'DbSet<MyEntity>()
.Where(s => EF.Property<bool>(s, __ef_filter___isDeleted_0) == False)' could not be translated.
因為(自然地)有很多地方使用了 AutoMapper,所以我也不想更改用于回傳我的 DTO 的代碼。調整 AutoMapper 配置就可以了。
PostgreSQL 用作底層資料庫,如果這有什么不同的話。
我需要如何配置我的查詢過濾器,以便現有代碼不會拋出例外?
// 編輯:
我已經簡化了我的例子,確切的代碼使用一個字串作為屬性名稱:
private readonly string _isDeleted = "IsDeleted";
builder.Entity<MyEntity>().Property<bool>(_isDeleted);
builder.Entity<MyEntity>().HasQueryFilter(m => EF.Property<bool>(m, _isDeleted) == false);
我可以改變那個變數。
uj5u.com熱心網友回復:
問題是_isDeleted用于指定屬性名稱的屬性名稱來自派生背景關系的實體欄位,并且背景關系的實體成員在全域查詢過濾器中被特別處理。基本上它們被替換為引數,在這種特殊情況下會導致“不可翻譯”結構。
解決方案是使用static或const代替,例如
private static readonly string _isDeleted = "IsDeleted";
或者
private const string _isDeleted = "IsDeleted";
uj5u.com熱心網友回復:
這里的那件事:
HasQueryFilter(b => EF.Property<string>(b, "_tenantId") == _tenantId);
已完成,因為該欄位是私有的。您仍然需要物體上的欄位來完成這項作業。但是,您可以在 automapper 配置中忽略它,這樣您就不需要調整 dtos。
uj5u.com熱心網友回復:
您不能將變數用于屬性名稱。在這種情況下,EF 創建了在這種情況下不可翻譯的引數。
解決方案是通過輔助函式動態生成查詢過濾器:
public static Expression<Func<T, bool>> GenerateDeletedFilter<T>(string propName)
{
var param = Expression.Parameter(typeof(T), "e");
var filter = Expression.Lambda<Func<T, bool>>(
Expression.Equal(
Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(bool) }, param,
Expression.Constant(propName)), Expression.Constant(false)), param);
return filter;
}
和用法:
private readonly string _isDeleted = "IsDeleted";
builder.Entity<MyEntity>().Property<bool>(_isDeleted);
builder.Entity<MyEntity>().HasQueryFilter(GenerateDeletedFilter<MyEntity>(_isDeleted));
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/376710.html
上一篇:從C#中的串列中洗掉串列項的屬性
