Initializer.Seed()在context.SaveChanges()

时间:2015-06-03 15:26:32

标签: c# entity-framework

我对EntityFramework相对较新(今天就开始使用它了!)

我有以下代码:

    public class DemoContext : DbContext
    {
        public DemoContext() : base("demoContext")
        {

        }

        public DbSet<BaseUser> Users {get; set;}
        public DbSet<BaseSession> Sessions {get;set;} 
     }

    public class DemoInitializer : DropCreateDatabaseAlways<DemoContext>
    {
        protected override void Seed(DemoContext context)
        {
            var staffUsers = new List<StaffUser>
            {
                new StaffUser {Id=1,Username="test",Password="test",DisplayName="test user",AccessFlags=(AccessFlags)2048 },
            };

            staffUsers.ForEach(su => context.Users.Add(su));
            context.SaveChanges();
        }
    }

但是每当调用context.SaveChanges();行时,它都会抛出以下异常:

  

类型的例外   发生'System.Data.Entity.Infrastructure.DbUpdateException'   EntityFramework.dll但未在用户代码中处理

     

其他信息:从ObjectStateEntry中检索值时出错。   有关详细信息,请参阅内部异常。

内在的例外是:

  

字典中没有给定的密钥。

虽然这个错误在这一点上对我来说并不是很重要,而谷歌搜索并没有产生任何答案,但我似乎设法将其归结为与公共财产DbSet<BaseSession> Sessions {get;set}有关。 DemoContext类 (我的意思是,如果我将其评论出来,那么错误就不会发生,我们就会离开!)

为什么会这样,什么是正确的解决方案?

如果我使用Initializer.Seed(),是否需要对DbContext中存在的所有DbSet属性执行某些操作?
我假设你实际上不必用数据填充它们,因为这没有意义吗?


完整例外的屏幕截图,因为它很有用! Screenshot of the full exception, incase it's useful!


修改

我已将其调整为BaseSession类的此特定实现的问题:

public class UniqueSession : BaseSession
{
     public Date DateOfSession { get; set; }
     public string Comments { get; set; }
}

正如您所看到的,使用自定义的Date类,我在这里从另一个问题中窃取:

    public class Date : IEquatable<Date>, IEquatable<DateTime>
    {
        public Date(DateTime date)
        {
            value = new DateTime(date.Date.Ticks, DateTimeKind.Unspecified);
            //value = date.Date;
        }

        public bool Equals(Date other)
        {
            return other != null && value.Equals(other.value);
        }

        public bool Equals(DateTime other)
        {
            return value.Equals(other);
        }

        public override string ToString()
        {
            return value.ToString();
        }
        public static implicit operator DateTime(Date date)
        {
            return date.value;
        }
        public static explicit operator Date(DateTime dateTime)
        {
            return new Date(dateTime);
        }

        private DateTime value;
    }

如果我将UniqueSession.DateOfSession切换为DateTime,则不会发生此错误?


编辑2
如果我更改Date类以使private DateTime value;实际上是公共属性(public DateTime value { get; set; }),则错误就会消失!

但为什么?

2 个答案:

答案 0 :(得分:2)

复杂类型(超出其他类型)是“在数据库中创建列”的快捷方式。

该类的一个公共财产的一列。该类中没有属性,没有要映射/创建的列。

这可能会使EF感到困惑。

答案 1 :(得分:1)

EF的类日期与其他未内置(并由EF处理)类型的日期类似  所以:
- DateOfSession是对日期的引用 - 日期(日期)是SQL Server上的表(以及上下文中的DbSet)

在这种情况下,EF可能正在寻找DbSet&lt; Date&gt;