目前我正在尝试为我的dBContext上的Asvateentity方法的一部分来处理实体的独特验证。我尝试解决的问题是在同时添加多个实体时,在命中数据库之前检测唯一的约束错误。在添加实体a和b时,是一个例子,确保a和b没有相同的名称。目前,我的唯一索引在数据库中最少地应用于它,我有以下代码可以在数据库中介绍时涵盖:

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."));
}
.

编辑

当“唯一键”由外键组成时是一个更复杂的情况。当对数据库进行时,您需要使用外键字段,但是当对本地缓存时,您不能总是说出ReferenceId == ReferenceId时,如果也刚刚添加参考实体,则为零。检查本地缓存是否是以下的正确方法是以下,或者我需要急于加载引用,因为在验证期间延迟加载关闭?

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