gpt4 book ai didi

entity-framework - 在 Entity Framework 代码优先方法中,两个字段的组合必须是唯一的。怎么会

转载 作者:行者123 更新时间:2023-12-03 23:38:33 28 4
gpt4 key购买 nike

我有两个类(class)联系人和群组

FirstNameLastName 的组合必须是唯一的,并且可以为单个联系人添加多个地址。我如何在 Entity Framework 代码优先方法中做到这一点?

public class Contacts
{
[Key]
public int ContactID { get; set; }
[ForeignKey("Group")]
public int GroupID { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string Number { get; set; }
[Required]
[EmailAddress]
public string EmailId { get; set; }
[DataType(DataType.Date)]
public DateTime CreateDate { get; set; }
public DateTime? ModifiedDate { get; set; }

public virtual Groups Group { get; set; }
}

public class Groups
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int GroupID { get; set; }
[Required]
public string GroupName { get; set; }
[Required]
public string GroupDiscription { get; set; }
public DateTime CreateDate { get; set; }
public DateTime ModifiedDate { get; set; }
}

最佳答案

检查重复项意味着您必须到数据库中进行验证。在 Entity Framework Code First 中,这意味着使用 DbContext。参见 Implementing Validation in the Context with ValidateEntity有关如何在 Entity Framework 中进行验证的很好的解释。

您应该在上下文类中覆盖 ValidateEntity 方法:

    protected override DbEntityValidationResult ValidateEntity(
DbEntityEntry entityEntry,
IDictionary<object, object> items)
{
//base validation for Data Annotations, IValidatableObject
var result = base.ValidateEntity(entityEntry, items);

//You can choose to bail out before custom validation
//if (result.IsValid)
// return result;

CustomValidate(result);
return result;
}

private void CustomValidate(DbEntityValidationResult result)
{
ValidateContacts(result);
ValidateOrganisation(result);
}

private void ValidateContacts(DbEntityValidationResult result)
{
var c = result.Entry.Entity as Contact;
if (c== null)
return;

if (Contacts.Any(a => a.FirstName == c.FirstName
&& a.LastName == c.LastName
&& a.ID != c.ID))
result.ValidationErrors.Add(
new DbValidationError("Name",
"Name already exists"));
}

private void ValidateOrganisation(DbEntityValidationResult result)
{
var organisation = result.Entry.Entity as Organisation;
if (organisation == null)
return;

if (Organisations.Any(o => o.Name == organisation.Name
&& o.ID != organisation.ID))
result.ValidationErrors.Add(
new DbValidationError("Name",
"Name already exists"));
}

调用 SaveChanges 时会触发此验证。如果有任何错误,将抛出 DbEntityValidationException

关于结构化验证的更多信息 here

对于“腰带和大括号”方法,我还在迁移中的自然键上向数据库添加了唯一索引。从而防止由于不通过 Entity Framework 向数据库插入而导致无效数据:

public partial class Adduniqueindexes : DbMigration
{
public override void Up()
{
//You have to use Sql if the column is nullable:
Sql(@"CREATE UNIQUE INDEX IX_UPRN ON Properties(UPRN, OrganisationID)
WHERE UPRN IS NOT NULL"));
CreateIndex("dbo.Organisations",
"Name",
unique: true,
name: "IX_NaturalKey");
CreateIndex("dbo.Contacts",
new string[] { "FirstName", "LastName" },
unique: true,
name: "IX_NaturalKey");
}

public override void Down()
{
DropIndex("dbo.Properties", "IX_UPRN");
DropIndex("dbo.Organisations", "IX_NaturalKey");
DropIndex("dbo.Contacts", "IX_NaturalKey");
}
}

关于索引的更多信息 here

补充说明从 EF6.1 开始,可以通过添加数据属性来指示应在字段上创建索引:

[Index("IX_NaturalKey", IsUnique = true)]
[Required] //If the field is nullable then you have to create the index in the migration
//using sql, so I'd only expect IsUnique = true on a Required field
[StringLength(256)] //indexes must be less than 900 bytes in Sql Server,
//so nvarchar(max) will not do
public string Name{ get; set; }

关于entity-framework - 在 Entity Framework 代码优先方法中,两个字段的组合必须是唯一的。怎么会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18714550/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com