错误:违反PRIMARY KEY约束' PK_dbo.CompanyDtoes'。 无法在对象' dbo.CompanyDtoes'中插入重复键。该 重复键值为(b20a140d-440b-4a41-b2c3-6763fa752246)。该 声明已被终止。
PersonDto
public class PersonDto : PartnerDto, IPartner
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public string BirthPlace { get; set; }
public string MothersName { get; set; }
public string TaxId { get; set; }
public List<CompanyDto> OwnedCompanies { get; set; }
/// <summary>
/// Partner címe(i)
/// </summary>
public List<PersonAddressDto> Addresses { get; set; }
public PersonDto()
{
OwnedCompanies = new List<CompanyDto>();
Addresses = new List<PersonAddressDto>();
}
}
CompanyDto
public class CompanyDto : PartnerDto, IPartner
{
public string TaxNumber { get; set; }
public int CompanyValue { get; set; }
public List<PersonDto> Owners { get; set; }
/// <summary>
/// Partner címe(i)
/// </summary>
public List<CompanyAddressDto> Addresses { get; set; }
public CompanyDto()
{
Owners = new List<PersonDto>();
Addresses = new List<CompanyAddressDto>();
}
}
我的DBContext:
public class PartnerDBContext : DbContext
{
public DbSet<PersonDto> Persons { get; set; }
public DbSet<CompanyDto> Companies { get; set; }
public DbSet<AddressDto> Addresses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PersonDto>()
.HasKey(k => k.PartnerId);
modelBuilder.Entity<CompanyDto>()
.HasKey(k => k.PartnerId);
modelBuilder.Entity<AddressDto>()
.HasKey(k => k.ID);
}
}
我尝试插入一个新人,其中包含已存在公司的一些参考资料:
public bool InsertPerson(PersonDto personToInsert)
{
try
{
using (var db = new PartnerDBContext())
{
db.Persons.Add(personToInsert);
db.SaveChanges();
}
}
catch (Exception ex)
{
return false;
}
return true;
}
我的问题是,我无法插入它,因为它写了违反CompanyDto的主键。我知道它已经存在,我不想添加新的,但我应该如何添加它?我在从WWP调用的WCF服务中使用它。遗憾的是,无法使用UWP中的DataAnnonations(这是一个bug),所以我使用了ModelBuilder ......
答案 0 :(得分:0)
public bool InsertPerson(PersonDto personToInsert)
{
try
{
using (var db = new PartnerDBContext())
{
var companies = personToInsert.OwnedCompanies;
personToInsert.OwnedCompanies = new List<CompanyDto>();
foreach (var company in companies)
{
var companyInDb = db.Companies.Find(company.PartnerId);
personToInsert.OwnedCompanies.Add(companyInDb);
}
db.Persons.Add(personToInsert);
db.SaveChanges();
}
}
catch (Exception ex)
{
return false;
}
return true;
}
我找到了解决方案,如果我从数据库中获取公司,它可以保存所有内容。
答案 1 :(得分:0)
问题在于,当您将人员实体添加到上下文时,它还会添加相关实体并将其标记为Added
(即新的)。 SaveChanges()
反过来尝试将它们插入数据库中,您将获得重复的PK异常。
您发布的解决方案有效,但涉及检索相关对象的不必要的数据库跳转。由于您知道它们存在,您可以通过简单地将它们预先附加到上下文来避免这种情况,这会将它们标记为Unchanged
(即存在)。然后SaveChanges
将仅插入人员记录和链接。
using (var db = new PartnerDBContext())
{
foreach (var company in personToInsert.OwnedCompanies)
db.Companies.Attach(company);
db.Persons.Add(personToInsert);
db.SaveChanges();
}
或者,您可以在将此人添加到上下文后将其标记为Unchanged
:
using (var db = new PartnerDBContext())
{
db.Persons.Add(personToInsert);
foreach (var company in personToInsert.OwnedCompanies)
db.Entry(company).State = EntityState.Unchanged;
db.SaveChanges();
}
在我的测试中(最新的EF6.1.3,与发布的样本中一样短暂的新DbContext
)这两种方法都有效。