【问题标题】:Initializer.Seed() throws exception on context.SaveChanges()Initializer.Seed() 在 context.SaveChanges() 上抛出异常
【发布时间】:2015-06-05 16:31:03
【问题描述】:

我对 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 检索值时出错。 有关详细信息,请参阅内部异常。

内部异常是:

给定的键不在字典中。

虽然此时此错误对我来说并没有太大意义,而且谷歌搜索也没有产生任何答案,但我似乎设法将其归结为与 DemoContext 类上的公共属性 DbSet&lt;BaseSession&gt; Sessions {get;set} 相关 (我的意思是,如果我把它注释掉,错误就不会发生,我们就走了!)

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

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

.
完整异常的屏幕截图,以防它有用!

.
编辑

我认为这是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; }),错误就会消失!

但是为什么呢?

【问题讨论】:

  • 您确定对会话集进行注释吗?多试几次。
  • 100% 确保注释掉这条线会让一切都变得美好而美好。
  • 您能否发布 User、StaffUser 和 Session 类,至少它们是如何相互关联的?
  • @HenkHolterman - 我已经更新了我的问题,因为我还有一点。似乎与用作继承类之一的类型的自定义类有关?
  • 另外,BaseUser 是一个抽象类,由 StaffUser 实现。 BaseSession(也不是任何派生类型)与 BaseUser 或 StaffUser 无关

标签: c# entity-framework


【解决方案1】:

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

类的一个公共属性的一列。如果类中没有属性,则没有要映射/创建的列。

这可能会使 EF 感到困惑。

【讨论】:

    【解决方案2】:

    EF 的 Date 类与任何其他非内置(并由 EF 处理)类型一样。
    所以:
    - DateOfSession 是对 Date
    的引用 - Date(日期)是 SQL Server 上的一个表(以及上下文上的一个 DbSet)

    在这种情况下,EF 可能正在寻找 DbSet

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-24
      • 2011-05-25
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多