一对多关系映射错误,代码优先6.0

时间:2014-04-17 12:46:52

标签: c# .net entity-framework ef-code-first

我有两个实体任务和尝试,一个任务有许多尝试,所以我将实体定义如下。

public class Task
{
    public long TaskId { get; set; }
    [Required]
    public int DestinationNumber { get; set; }
    [Required]
    public int CountryCode { get; set; }
    // blah blah
    public virtual ICollection<Attempt> Attempts { get; set; }
}

public class Attempt
{
    public long Id { get; set; }
    public string AttemptsMetaData { get; set; }
    public DateTime Time { get; set; }
    public bool Answered { get; set; }
    public DateTime Disconnected { get; set; }
    // foreign key
    public long TaskId { get; set; }
    public virtual Task Task { get; set; }
}

我使用Code First Relationships Fluent API来映射关系。

public class OutboundContext : DbContext
{
    public DbSet<Task> Tasks { get; set; }
    public DbSet<Attempt> Attempts { get; set; }
    public OutboundContext()
        : base("Outbound")
    {
        Database.SetInitializer<OutboundContext>(new CreateDatabaseIfNotExists<OutboundContext>());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Task>().HasMany(t => t.Attempts).WithRequired();
    }

单元测试通过,但是当我检查表格[Outbound]时。[dbo]。[尝试]。列是

   [Id]
  ,[AttemptsMetaData]
  ,[Time]
  ,[Answered]
  ,[Disconnected]
  ,[Task_TaskId]
  ,[Task_TaskId1]

您看到第一个[Task_TaskId]错误,并且还生成了一个额外的列[Task_TaskId1]

有什么问题?

修改

TaskId应该是外键。

// Add dummy data
        public bool AddAttempt(List<Attempt> attempt)
        {
            using (OutboundContext db = new OutboundContext())
            {
                foreach (var item in attempt)
                {
                    db.Attempts.Add(item);
                }
                try
                {
                    db.SaveChanges();
                    return true;
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
            }
        }

        List<Attempt> attempts = new List<Attempt>();
        Attempt objAtt = new Attempt();
        long id = 123456789;
        objAtt.AttemptId = id;
        objAtt.Time = DateTime.Now;
        objAtt.AttemptsMetaData = "test";
        objAtt.Answered = true;
        objAtt.Disconnected = DateTime.Now;
        objAtt.TaskId = 33333333;
        attempts.Add(objAtt);
        //Then call AddAttempt

3 个答案:

答案 0 :(得分:1)

似乎问题发生的原因是您在Task类中遇到的Collection of Attempt实际上没有被引用到您在Attempt类中的“Task”属性。我的建议是在Attempt类中明确声明一个int TaskId属性,并按以下方式为Attempt Class进行映射:

HasRequired(attempt => attempt.Task)
            .WithMany(task => task.Attempts)
            .HasForeignKey(attempt => attempt.TaskId);

希望这有帮助。

答案 1 :(得分:0)

使用Fluent API。

modelBuilder.Entity<Task>().HasMany(t => t.Attempts).WithRequired(t=>t.Task).HasForeignKey(t => t.TaskId);

另一点是我们必须以正确的顺序保存表。类似的东西:

            db.Tasks.Add(task);
            db.SaveChanges();
            Attempt a = new Attempt() { Id = Guid.NewGuid(), TaskId = task.TaskId, AttemptsMetaData = "1" };
            db.Attempts.Add(a);
            db.SaveChanges();

否则它在SQL Server Management Studio中的TaskId上显示“无效列”。

答案 2 :(得分:-1)

我对OnModelCreating做了一个非常小的改动,它没有在数据库中创建一个额外的[Task_TaskId1]:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Task>().HasMany(t => t.Attempts);
}