Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net EF代码第一个CTP 5:验证依赖于其他实体的实体(例如唯一约束)_.net_Entity Framework_Ef Code First - Fatal编程技术网

.net EF代码第一个CTP 5:验证依赖于其他实体的实体(例如唯一约束)

.net EF代码第一个CTP 5:验证依赖于其他实体的实体(例如唯一约束),.net,entity-framework,ef-code-first,.net,Entity Framework,Ef Code First,对于依赖于使用POCO的其他域实体的域实体的验证,有哪些最佳实践是在首先实现基于EF代码的ORM时创建的 下面是我正在尝试解决的情况:我有一个表示客户端计算机的类,该类的一个属性表示计算机的IP。我需要它是唯一的,但我找不到一个优雅的解决方案来强制执行该约束。目前,我在服务层中更新/插入实体 --更新-- 我知道EF不支持唯一约束,并且我已经将约束添加到数据库表中,但是我宁愿在访问数据库之前捕获约束。我一直在寻找一种更好的方法来处理通常依赖于其他实体的验证,并以unique约束为例 --更新日期

对于依赖于使用POCO的其他域实体的域实体的验证,有哪些最佳实践是在首先实现基于EF代码的ORM时创建的

下面是我正在尝试解决的情况:我有一个表示客户端计算机的类,该类的一个属性表示计算机的IP。我需要它是唯一的,但我找不到一个优雅的解决方案来强制执行该约束。目前,我在服务层中更新/插入实体

--更新--

我知道EF不支持唯一约束,并且我已经将约束添加到数据库表中,但是我宁愿在访问数据库之前捕获约束。我一直在寻找一种更好的方法来处理通常依赖于其他实体的验证,并以unique约束为例

--更新日期:3/28/2010--

以下是我当前处理IP唯一约束的方式(unitOfWork的类型为SqlMessageUnitOfWork:基本上它围绕我正在使用的DBContext进行包装,为所有相关表公开IDbSets),以供参考:

公共类ClientService:IClientService
{
公共验证结果插入客户端(客户端到客户端)
{
var existingClient=_unitOfWork.Clients.Where(x=>x.IP==clientDTO.IP).SingleOrDefault();
if(existingClient!=null)
{           
返回新的ValidationResult(“IP已在使用中。”,新[]{“IP”});
}
其他的
{
var newclient=newclient();
ClientEntityMapper.MapToEntity(clientDTO、newclient、_unitOfWork.Terminals);
_unitOfWork.Clients.Add(newclient);
_unitOfWork.Commit();
}
返回ValidationResult.Success;
}
...
私人工作单位;
公共客户端服务(IUnitOfWork unitOfWork)
{
_unitOfWork=unitOfWork;
}
}
公共接口工作单元
{
IDbSet消息{get;}
IDbSet终端{get;}
IDbSet客户端{get;}
IDbSet MessageDisplayInstances{get;}
无效提交();
}
公共类SqlMessageUnitOfWork:IUnitOfWork
{
只读VisualPagingDbContext\u context;
公共SqlMessageUnitOfWork()
{
_context=新的VisualPagingDbContext();
}
公共无效提交()
{
_SaveChanges();
}
公共IDbSet消息
{
获取{return\u context.Messages;}
}
公共设备终端
{
获取{return\u context.Terminals;}
}
公共IDbSet客户端
{
获取{return\u context.Clients;}
}
公共IDbSet MessageDisplayInstances
{
获取{return\u context.MessageDisplayInstances;}
}
}

唯一约束完全不受EF支持(),但这并不意味着您不能将它们添加到数据库表中(例如在自定义初始值设定项中)。您描述的是需要查询数据库的验证。它是一种业务验证,必须在需要时实施和执行。这不是EF将为您处理的事情。顺便说一句,CTP5是过时的版本。使用。

如果需要设置唯一约束,可以通过运行sql命令来完成

因此,无论您在哪里进行域模型配置,都可以添加一行来执行sql。因此,在您的情况下,应采用以下方法:

string script = "ALTER TABLE <table-name> ADD CONSTRAINT UniqueElement UNIQUE (<column-name>)";
context.Database.SqlCommand(script);
string script=“ALTER TABLE ADD CONSTRAINT uniquelement UNIQUE()”;
context.Database.SqlCommand(脚本);

要在实体验证中添加唯一性检查,我在上下文中重写了ValidateEntity,并添加了以下内容:

if (entityEntry.Entity is Role &&
            (entityEntry.State == EntityState.Added || entityEntry.State == EntityState.Modified))
        {
            var role = entityEntry.Entity as Role;

            if (!string.IsNullOrEmpty(role.ShortName))
            {
                if (
                    Roles.Any(
                        p => p.ShortName.ToLower() == role.ShortName.ToLower() && !p.RoleID.Equals(role.RoleID)))
                {
                    result.ValidationErrors.Add(new DbValidationError("ShortName", "Role Short Name already exists"));
                    return result.ValidationErrors.Count > 0 ? result : base.ValidateEntity(entityEntry, items);
                }
                //Remeber to check local collection - otherwise we could end up saving two or more at once that are duplicated
                if (
                    Roles.Local.Count(p => p.ShortName.ToLower() == role.ShortName.ToLower() && !p.Equals(role)) > 0)
                {
                    result.ValidationErrors.Add(new DbValidationError("ShortName", "Role Short Name already exists"));
                    return result.ValidationErrors.Count > 0 ? result : base.ValidateEntity(entityEntry, items);
                }
            }
        }
如果需要获取EF以在数据库中创建约束/索引等,请参见:


感谢您让我知道4.1已经过时。您没有展示您当前处理验证的方式,因此我们不知道您希望有什么更好的方式。我说我是在服务层处理的。我将通过输入实际代码来更新我的问题。我认为如果不查询数据库,就无法验证依赖属性。我在我的BaseRepository类中将IsValid()方法定义为虚拟方法,并在其他存储库中重写它,在服务层的单个方法中进行所有验证。我同意,尽管我忘记了这个问题的细节,但我不再真正使用这样的服务类。对我来说,他们隐藏了所有肮脏的小秘密,当他们在那里谈论基于存储库/域/服务的体系结构时,没有人谈论这些秘密。您无法回避验证(或一般业务逻辑)有时依赖于其他实体的状态这一事实,这往往会被推到“服务层”。对我来说,它直接属于业务模型,因此我认为它违反了层责任。我的问题不是如何创建唯一的约束,而是如何在我的应用程序代码中更好地对它们建模。
if (entityEntry.Entity is Role &&
            (entityEntry.State == EntityState.Added || entityEntry.State == EntityState.Modified))
        {
            var role = entityEntry.Entity as Role;

            if (!string.IsNullOrEmpty(role.ShortName))
            {
                if (
                    Roles.Any(
                        p => p.ShortName.ToLower() == role.ShortName.ToLower() && !p.RoleID.Equals(role.RoleID)))
                {
                    result.ValidationErrors.Add(new DbValidationError("ShortName", "Role Short Name already exists"));
                    return result.ValidationErrors.Count > 0 ? result : base.ValidateEntity(entityEntry, items);
                }
                //Remeber to check local collection - otherwise we could end up saving two or more at once that are duplicated
                if (
                    Roles.Local.Count(p => p.ShortName.ToLower() == role.ShortName.ToLower() && !p.Equals(role)) > 0)
                {
                    result.ValidationErrors.Add(new DbValidationError("ShortName", "Role Short Name already exists"));
                    return result.ValidationErrors.Count > 0 ? result : base.ValidateEntity(entityEntry, items);
                }
            }
        }