asp.net ef代码首先使用外键重复元素

时间:2018-09-27 18:34:15

标签: asp.net ef-code-first

我有以下代码:

    public Exam CreateExam(string name, List<Question> questions, DateTime timeNow)
    {
        User user = GetUserByName(name);

        Exam exam = new Exam()
        {
            Questions = questions,
            StartDate = timeNow,
            User = user
        };
        Context.Exams.Add(exam);
        Context.SaveChanges();
        return exam;
    }

考试:

public class Exam
{
    public int Id { get; set; }
    public DateTime StartDate { get; set; }
    public User User { get; set; }
    public virtual List<Question> Questions { get; set; }
}

用户具有基本的用户信息。

我的问题是,当我为用户创建考试时,保存更改还会将新用户添加到数据库中,只是ID不同。如何防止这种情况并使它理解要链接到现有用户?

谢谢!

编辑:GetUserByName():

Context.Database.SqlQuery<User>("Select * from Users where name = @name", new SqlParameter("name", name)).FirstOrDefault();

2 个答案:

答案 0 :(得分:0)

当您使用SqlQuery来获取用户时,由于实体框架可以写任意查询并将结果映射到User类,因此不会被实体框架跟踪。因此,当您提及他时,EF认为他是新人。要解决此问题,您应该手动将他附加到上下文:

User user = GetUserByName(name);
Context.Users.Attach(user);

答案 1 :(得分:0)

基于Slava Utesinov的答案实体框架的更改跟踪器在从原始查询(例如:

)获取时不跟踪实体更改。
Context.Database.SqlQuery<User>("Select * from Users where name = @name", new SqlParameter("name", name)).FirstOrDefault();

因此,当您调用SaveChanges()方法时,实体框架更改跟踪程序会将用户实体状态检测为已添加(新实体)

1。您可以使用DbSet.SqlQuery代替Database.SqlQuery,因为DbSet.SqlQuery将由上下文跟踪:

Context.Users.SqlQuery("Select * from Users where name = @name", new SqlParameter("name", name)).FirstOrDefault();

或 2.您可以将实体作为不变状态附加到当前上下文dbset