문제

현재 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;
}
.

두 번째 함수는 외래 키 참조로 만들어진 고유 키의 경우를 다룹니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top