3

我正在使用带有代码优先方法的 Entity Framework 5。

我正在尝试做一个测试系统。它有五个具有一对一和一对多关系的类。一个测试有一个 TestInfo,一个用户有多个 TestResult,一个 TestResult 有一个 TestInfo 和多个 QuestionResult。它们在这里(没有一些简单的值类型属性):

public class TestInfo
{
    [Key]
    public virtual string Name { get; set; }
    public virtual TimeSpan Duration { get; set; }
}

public class Test
{
    [Key]
    public virtual int TestId { get; set; }
    public virtual TestInfo Info { get; set; }
    //some other stuff
    //...
}

public class User
{
    [Key]
    public virtual string Login { get; set; }

    List<TestResult> _results = new List<TestResult>();
    public virtual List<TestResult> Results
    {
        get { return _results; }
        set { _results = value; }
    }
    //...
}

public class TestResult
{
    [Key]
    public virtual int TestResultId { get; set; }
    public virtual TestInfo TestInfo { get; set; }
    //...

    private List<QuestionResult> _questionResults = new List<QuestionResult>();
    public virtual List<QuestionResult> QuestionResults
    {
        get { return _questionResults; }
        set { _questionResults = value; }
    }
}

public class QuestionResult
{
    [Key]
    public virtual int QuestionResultId { get; set; }
    //...
}

我的背景:

class TestContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Test> Tests { get; set; }
}

我正在尝试将新的 TestResult 添加到现有用户的现有测试(TestInfo 相同):

public void AddTestResult(TestResult result)
{
    User user = _context.Users.Include(u => u.Results).FirstOrDefault(u => u.Login == _currentLogin);
    TestInfo existingTestInfo = _context.Tests.Where(t => t.Info.Name == result.TestInfo.Name).FirstOrDefault().Info;
    result.TestInfo = existingTestInfo;
    user.Results.Add(result);
    _context.SaveChanges();
}

当我这样做时,EF 会抛出异常:

{“违反 PRIMARY KEY 约束 'PK_dbo.TestInfoes'。无法在对象 'dbo.TestInfoes' 中插入重复键。重复键值为 (First test)。\r\n语句已终止。”}

如果我从 TestResult 类中删除 QuestionResults 属性,一切正常。这对我来说似乎很奇怪。我究竟做错了什么?

4

3 回答 3

0

Swap these two lines:

user.Results.Add(result);
result.TestInfo = existingTestInfo;

user.Results.Add(result) marks the whole object graph as Added.

于 2013-05-31T12:30:22.957 回答
0

尝试这个:

TestInfo existingTestInfo = _context.Tests.Where(t => t.Info.Name == result.TestInfo.Name).Include(i => i.TestInfos).FirstOrDefault().Info;

在我包含子表之前,我也遇到了这个错误,然后一切正常。

于 2014-01-27T08:34:35.663 回答
-1

我在单独的数据访问层 (DAL) 中使用 EF5 框架时遇到了这个问题。为了修复它,我不得不遍历外键类并重新附加它们。我怀疑有更好的方法,但这让我通过了帖子。

if (db.Entry(result.TestInfo).State == EntityState.Detached)
    db.Entry(result.TestInfo).State = EntityState.Modified;

让我知道这是否有帮助!

于 2013-06-28T15:35:06.127 回答