EF插入与关系

时间:2014-02-11 22:35:19

标签: entity-framework ef-code-first

我正在创建一个MVC 5网站来跟踪高尔夫锦标赛的结果。我有3个关键表,事件有很多结果 Golfer 有很多结果。因此,对于 Result 表中的任何行,我都可以链接到高尔夫球手和事件。

我首先使用EF6代码继续保存到SQL Server。

这是我的事件poco:

public class Event
    {
        public int EventId { get; set; }
        public string VenueName { get; set; }
        public string CourseName { get; set; }
        public String FirstTeeOff { get; set; }
        public DateTime EventDate { get; set; }
        public decimal Fee { get; set; }
        public virtual ICollection<Result> Results { get; set; }
    }

高尔夫球手:

public class Golfer
    {
        public int GolferId { get; set; }
        public string FirstName { get; set; }
        public string Surname { get; set; }
        public int CurrentHandicap { get; set; }
        public string Email { get; set; }
        public string Telephone { get; set; }
        public virtual ICollection<Result> Results { get; set; }
    }

结果:

public class Result
    {
        public int ResultId { get; set; }
        public Golfer Golfer { get; set; }
        public Event Event { get; set; }
        public bool Attendance { get; set; }
        public int HandicapPlayed { get; set; }
        public int ScoreCarded { get; set; }

        public Result()
        {
            Event = new Event();
            Golfer = new Golfer();
        }
    }

这是我的模特背景:

public class ModelContext : IdentityDbContext<ApplicationUser>, SANDGolf.DataLayer.IModelContext
    {
        public ModelContext() : base("ModelContextConString") { }

        public virtual DbSet<SANDGolf.DomainClasses.Golfer> Golfers { get; set; }
        public virtual DbSet<SANDGolf.DomainClasses.Event> Events { get; set; }
        public virtual DbSet<SANDGolf.DomainClasses.Result> Results { get; set; }
    }

我正在使用以下控制器操作尝试插入结果表以记录出勤率。

[HttpPost]
        [Authorize]
        public ActionResult ExpectedAttendance(ExpectedAttendanceViewModel eaVM)
        {
            try
            {
                foreach(GolferAttendanceViewModel gaVM in eaVM.GolferAttendanceViewModel)
                {
                    DomainClasses.Result resultDomain = new DomainClasses.Result();

                    resultDomain.Attendance = gaVM.Attending;
                    resultDomain.Event.EventId = eaVM.Event.EventId;
                    resultDomain.Golfer.GolferId = gaVM.Golfer.GolferId;

                    _context.Entry(resultDomain).State = EntityState.Modified;
                    _context.SaveChanges();
                }

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

当行_context.SaveChanges();执行我得到以下错误:

存储更新,插入或删除语句影响了意外的行数(0)。自实体加载后,实体可能已被修改或删除。刷新ObjectStateManager条目。

我是EF的新手,如果有人能让我知道我哪里出错,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

导航属性也需要是虚拟的。

public virtual Golfer Golfer { get; set; }
public virtual Event Event { get; set; }

此外,像Scott Corbett所说,你的新实体不应该修改状态,而应添加状态:

_context.Entry(resultDomain).State = EntityState.Added;

......或者更好:

_context.Results.Add(resultDomain);

答案 1 :(得分:1)

我建议切换到外键关联。例如:

public virtual Golfer Golfer {get;set;}

将成为:

public int GolferId {get;set;}
public virtual Golfer Golfer {get;set;}

使用这种方法,你可以设置例如:

Golfer myGolfer = getGolferById(1); // or gaVM.Golfer.GolverId;
Result.GolferId = myGolfer.GolferId;

您可以在my blog上了解详情。

在向数据库添加新实体时,不应使用:

_context.Entry(resultDomain).State = EntityState.Modified;

但请使用@ danludwig的解决方案。