感謝Jeffcky大佬的博客:
EntityFramework Core 2.0全局過濾 (HasQueryFilter) https://www.cnblogs.com/CreateMyself/p/8491058.html什么是值對象
沒有唯一的標識,固定不變的,表示一個具體的概念,用來描述一個東西的特征,代表是什么,使用時直接添加或替換,值對象在遷移時,會以字段的形式遷移到數據庫中軟刪除
定義刪除的接口
public interface ISoftDelete
{
bool IsDeleted { get; set; }
}
創建模型實現ISoftDelete接口
public class UserInfo : IAggregationRoot, ISoftDelete
{
public Guid Id { get; set; }
public string UserName { get; private set; }
public string UserPassword { get; private set; }
public string UserPhone { get; private set; }
public Address Address { get; private set; }
public bool IsDeleted { get; set; }
}
[Owned]
public class Address:IValueObject
{
public string Province { get;private set; }
public string City { get; private set; }
public string County { get; private set; }
public string AddressDetails { get; private set; }
}
Lamda的擴展以及Code First 遷移配置
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//設置軟刪除
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var parameter = Expression.Parameter(entityType.ClrType);
//查詢類上面是否有Owned(值對象)的特性
var ownedModelType = parameter.Type;
var ownedAttribute = Attribute.GetCustomAttribute(ownedModelType, typeof(OwnedAttribute));
if (ownedAttribute == null)
{
var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool));
var isDeletedProperty =
Expression.Call(propertyMethodInfo, parameter, Expression.Constant("IsDeleted"));
BinaryExpression compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeletedProperty,
Expression.Constant(false));
var lambda = Expression.Lambda(compareExpression, parameter);
modelBuilder.Entity(entityType.ClrType).HasQueryFilter(lambda);
}
}
}
在這里需要過濾掉值對象的類,在值對象的類上面聲明一個特性,通過該特性過濾掉該值對象, 如果該類是值對象就直接跳過,不過濾值對象EF CORE會給值對象附加一個IsDeleted的字段,EF CORE執行中會報錯,提示找不到該字段
Owned是EF CORE 配置值對象的特性,可以去自定義特性,在每一個值對象上面聲明,在OnModelCreating 過濾掉包含這個特性的類
最終實現的代碼:
public async Task
>> GetUserList(SearchUserDto input)
{
Expression
> where = e => e.IsDisable == false; if (!string.IsNullOrEmpty(input.SearchName)) { where = where.And(e => e.UserName.Contains(input.SearchName)); }
if (!string.IsNullOrEmpty(input.SearchPwd))
{
where = where.And(e => e.UserPhone.Contains(input.SearchPwd));
}
var userList = await _userRepository.LoadEntityListAsync(where, e => e.UserName, "asc", input.PageIndex, input.Pagesize);
var total = await _userRepository.GetEntitiesCountAsync(where);
var userDtoList = userList.MapToList<UserInfo, UserDto>();
HeaderResult<List<UserDto>> result = new HeaderResult<List<UserDto>>
{
IsSucceed = true,
Result = userDtoList,
Total = total
};
return result;
}
</pre>
