我们使用的是EF5和sql Server 2012以下两个类:
public class Question { public Question() { this.Answers = new List<Answer>(); } public int QuestionId { get; set; } public string Title { get; set; } public virtual ICollection<Answer> Answers { get; set; } } public class Answer { public int AnswerId { get; set; } public string Text { get; set; } public int QuestionId { get; set; } public virtual Question Question { get; set; } }
映射如下:
public class AnswerMap : EntityTypeConfiguration<Answer> { public AnswerMap() { // Primary Key this.HasKey(t => t.AnswerId); // Identity this.Property(t => t.AnswerId) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
数据库DDL
CREATE TABLE Answer ( [AnswerId] INT IDENTITY (1,1) NOT NULL,[QuestionId] INT NOT NULL,[Text] NVARCHAR(1000),CONSTRAINT [PK_Answer] PRIMARY KEY CLUSTERED ([AnswerId] ASC) )";
以下是我尝试过的结果:
这适用于一个孩子:
var a = new Answer{ Text = "AA",QuestionId = 14 }; question.Answers.Add(a); _uow.Questions.Update(question); _uow.Commit();
这不适用于多个孩子:
错误:ObjectStateManager中已经存在具有相同密钥的对象. ObjectStateManager无法跟踪具有相同键的多个对象.
var a = new Answer{ AnswerId = 0,Text = "AAA",QuestionId = 14 }; var b = new Answer { AnswerId = 0,Text = "BBB",QuestionId = 14 }; question.Answers.Add(a); question.Answers.Add(b); _uow.Questions.Update(question); _uow.Commit();
这不适用于多个孩子:
它创建AnswerID的1000和1001,但我想要由数据库创建新的Id.
var a = new Answer{ AnswerId = 1000,QuestionId = 14 }; var b = new Answer { AnswerId = 1001,QuestionId = 14 }; question.Answers.Add(a); question.Answers.Add(b); _uow.Questions.Update(question); _uow.Commit();
不行:
编译器错误.不能将null转换为int
var a = new Answer{ AnswerId = null,QuestionId = 14 }; var b = new Answer { AnswerId = null,QuestionId = 14 }; question.Answers.Add(a); question.Answers.Add(b); _uow.Questions.Update(question); _uow.Commit();
不行:
ObjectStateManager无法跟踪具有相同键的多个对象.
var a = new Answer{ Text = "AAA",QuestionId = 14 }; var b = new Answer { Text = "BBB",QuestionId = 14 }; question.Answers.Add(a); question.Answers.Add(b); _uow.Questions.Update(question); _uow.Commit();
在我的应用程序中,我有一个或多个新的Answer对象在客户端上生成,然后发送到服务器.上面我正在模拟将会发生什么,而不会增加客户端的问题.请注意,将所有答案添加到Question对象都是在客户端上完成的,然后将JSON字符串复制到服务器.然后将它反序列化为一个问题对象,如下所示:
public HttpResponseMessage PutQuestion(int id,Question question) { _uow.Questions.Update(question); _uow.Commit();
我想要使用新的身份标识ID创建每个答案对象,将这些对象添加到问题对象中,并使问题对象以正常方式返回.
我不知道如何做到这一点.我迄今为止所做的一切简单测试都无效.请注意,这是我们小组成员早些问题的一个变体,这个问题不太清楚,我正在试图关闭.这个问题我希望更清楚.
笔记:
这是更新编码的方式:
public virtual void Update(T entity) { DbEntityEntry dbEntityEntry = DbContext.Entry(entity); if (dbEntityEntry.State == EntityState.Detached) { DbSet.Attach(entity); } dbEntityEntry.State = EntityState.Modified; }
解决方法
你提到你要加两次吗?
question.Answers.Add(a); question.Answers.Add(a);
通常,要添加其身份标识的项目,您必须跳过设置该ID.您还应该将[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]属性添加到这些ID中:
public class Answer { [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int AnswerId { get; set; } public string Text { get; set; } public int QuestionId { get; set; } public virtual Question Question { get; set; } }
并添加如下所示的数据:
var a = new Answer{ Text = "AAA",QuestionId = 14 }; var b = new Answer { Text = "BBB",QuestionId = 14 }; dbContext.Answers.Add(a); dbContext.Answers.Add(b); dbContext.SaveChanges(); // ...