我有这样的实体:
public class Partner
{
public string ID { get; set; }
public string Name { get; set; }
public string PersonId { get; set; }
public int ProjectId { get; set; }
#region Navigation Properties
public virtual Person Person { get; set; }
public virtual Project Project { get; set; }
#endregion
}
public class Person
{
public string ID { get; set; }
public string Username { get; set; }
#region Navigation Properties
public virtual ICollection<Partner> Partners { get; set; }
#endregion
}
public class Project
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime DateStart { get; set; }
public DateTime DateEnd { get; set; }
public string Client { get; set; }
#region Navigation Properties
public ICollection<Partner> Partners { get; set; }
#endregion
}
当我插入新项目时,我在Partners
属性(Project
类)现有合作伙伴或Person
属性(Partner
类)现有人员。发生这种情况时,会发生“违反PRIMARY KEY”的异常。
我的代码Projects
是这样的:
//GetAllProject return IList<ProjectModel>
var projects = this.findProjectService.GetAllProjects();
foreach(var project in projects)
{
var projectDb = context.Project.Where(e => e.Id == project.Id).FirstOrDefault();
if (projectDb == null)
{
logger.Debug("Try add new project {0}", project.Name);
var newProject = Mapper.Map<ProjectModel, Project>(project);
context.Project.Add(newProject);
context.SaveChanges();
}
}
如何防止此问题?
编辑包含映射:
internal PartnerMap()
{
// Primary Key
this.HasKey(t => t.Id);
// Properties
this.Property(t => t.Id)
.IsUnicode(false);
this.Ignore(t => t.Name);
this.Property(t => t.PersonId)
.IsUnicode(false);
// Table
this.ToTable("Partner");
// Relations
this.HasRequired(t => t.Project)
.WithMany(r => r.Partners)
.HasForeignKey(t => t.ProjectId)
.WillCascadeOnDelete(false);
this.HasRequired(t => t.Person)
.WithMany(r => r.Partners)
.HasForeignKey(t => t.PersonId)
.WillCascadeOnDelete(false);
}
internal PersonMap()
{
// Primary Key
this.HasKey(t => t.Id);
// Properties
this.Property(t => t.Id)
.IsUnicode(false);
this.Ignore(t => t.Username);
// Table
this.ToTable("Person");
// Relations
}
internal ProjectMap()
{
// Primary Key
this.HasKey(t => t.Id);
// Properties
this.Property(t => t.Name)
.IsUnicode(false);
this.Property(t => t.Client)
.IsUnicode(false);
// Table
this.ToTable("Project");
// Relations
}
答案 0 :(得分:1)
这是因为mapping
,因为项目中的所有实体Partners
&amp; Persons
与上下文分离...请在下方检查正确的方法以使用映射...(这只是提示并非完整解决方案)
您还应该检查实体密钥的DatabaseGeneratedOption
是否为Identity
,或者您必须在每次插入时提交它们。
//GetAllProject return IList<ProjectModel>
var projects = this.findProjectService.GetAllProjects();
foreach(var project in projects)
{
var projectDb = context.Project.Where(e => e.Id == project.Id).FirstOrDefault();
if (projectDb == null)
{
// the next line will map you a newproject and all of the partners and persons inside the each parnter if found ...
// so you will get some entities which should be attached to the context in order for the ef to regonise that you mean not to insert new, but just to map them to the new project .. so
//var newProject = Mapper.Map<ProjectModel, Project>(project);
var newProject = context.Project.Create();
// you should setup your mapping to not map the ID and let each mapsetup to map an entity itself not it's child entities
newProject = Mapper.Map<ProjectModel, Project>(project);
// loop all partners in the PROJECT MODEL
foreach(var partner in project.PartnerModels)
ToPartners(partner, newProject.Partners);
context.Project.Add(newProject);
context.SaveChanges();
}
}
public void ToPartners(PartnerModel model, ICollection<Partner> partners)
{
var partnerDb = context.Partner.Where(e => e.Id == model.Id).FirstOrDefault();
if(parterDb == null)
{
var newPartner = context.Partner.Create();
newPartner = Mapper.Map<PartnerModel, Partner>(model);
// loop all persons in the PARTNER MODEL
foreach(var person in model.PersonsModel)
ToPersons(person, newPartner.Persons);
partners.Add(newPartner);
}
else
{
// loop all persons in the PARTNER MODEL
foreach(var person in model.PersonsModel)
ToPersons(person, partnerDb.Persons);
// here the partner is attached to the context so he will not insert a new one, it will just add (map) it to the project.
partners.Add(parterDb);
}
}
public void ToPersons(PersonModel model, ICollection<Person> persons)
{
// MAP IT
}