엔티티 프레임 워크 로컬 및 데이터베이스에서 고유 한 유효성 검사
-
21-12-2019 - |
문제
현재 DBContext에서 내 ValidateEntity 메소드의 일부로 엔티티에 대한 고유 한 유효성 검사를 처리하려고합니다. 내가 해결하려고하는 문제는 데이터베이스에 닿기 전에 고유 제한 조건 오류를 동시에 탐지하는 동시에 여러 엔티티를 추가 할 때입니다. A 및 B가 A와 B가 같은 이름을 갖지 않도록 Entity A와 B를 추가 할 때의 예는 다음과 같습니다. 현재 적어도 데이터베이스가 처리 할 고유 한 인덱스가 적용되므로 A가 이미 데이터베이스에있는 경우에 덮을 수있는 다음 코드가 있습니다.
if (this.Components.Any(x => x.Id != item.Id && x.Name == item.Name))
{
result.ValidationErrors.Add(new DbValidationError("Name", "There already exists another component with that name."));
}
.
다음을 수행하는 것보다 간단한 것이 있습니까?
Expression<Func<Component, bool>> predicate = x => x.Name == item.Name;
if (this.Components.Where(x => x.Id != item.Id).Any(predicate) || this.Components.Local.Where(x => x != item).Any(predicate.Compile()))
{
result.ValidationErrors.Add(new DbValidationError("Name", "There already exists another component with that name."));
}
.
편집
"독특한 키"가 외래 키로 구성된 경우는보다 복잡한 상황입니다. 데이터베이스에 반대 할 때, 로컬 캐시를 반대 할 때 외래 키 필드를 사용해야합니다. 로컬 캐시를 확인하는 올바른 방법은 유효성 검사 중에 참조가 꺼져 있기 때문에 참조를 간절히 알아야합니다.
this.Components.Local.Any(x => x != item && x.Name == item.Name && x.ReferenceId == item.ReferenceId && x.Reference == item.Reference)
. 해결책
내 문제를 해결하고 재사용을 제한하여 고유 한 유효성 검사를 돕기 위해 다음 확장을 추가했습니다.
public static bool UniqueCheck<TSource>(this DbSet<TSource> set, TSource item, Expression<Func<TSource, bool>> uniquePredicate) where TSource : class, IAuditEntity
{
var function = uniquePredicate.Compile();
var localContains = set.Local.Where(x => x != item).Any(function);
if (localContains) return localContains;
var remoteContains = set.Where(x => x.Id != item.Id).Any(uniquePredicate);
return remoteContains;
}
public static bool UniqueCheckWithReference<TSource>(this DbSet<TSource> set, TSource item, Expression<Func<TSource, bool>> uniquePredicate, Expression<Func<TSource, bool>> referenceUniquePredicate) where TSource : class, IAuditEntity
{
var localContains = set.Local.Where(x => x != item).Where(uniquePredicate.Compile()).Where(referenceUniquePredicate.Compile()).Any();
if (localContains) return localContains;
var remoteContains = set.Where(x => x.Id != item.Id).Where(uniquePredicate);
return false;
}
.
두 번째 함수는 외래 키 참조로 만들어진 고유 키의 경우를 다룹니다.
제휴하지 않습니다 StackOverflow