c# – 当孩子具有身份密钥时,如何使用EF将多个子实体添加到对象?

前端之家收集整理的这篇文章主要介绍了c# – 当孩子具有身份密钥时,如何使用EF将多个子实体添加到对象?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们使用的是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();

// ...

猜你在找的C#相关文章