c# - 升级到 Entity Framework 4.3.1 后未处理的异常

标签 c# entity-framework ef-code-first

错误:

未处理的异常:System.Data.SqlClient.SqlException:操作失败,因为表“PrivateMakeUpLessons”上已存在名为“IX_ID”的索引或统计信息。

模型(简化,构建在单独的测试项目中进行调试):

public abstract class Lesson
{
    public Guid ID { get; set; }
    public string Room { get; set; }
    public TimeSpan Time { get; set; }
    public int Duration { get; set; }
}

public abstract class RecurringLesson : Lesson
{
    public int DayOfWeek { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public string Frequency { get; set; }
}

public class PrivateLesson : RecurringLesson
{
    public string Student { get; set; }
    public string Teacher { get; set; }
    public virtual ICollection<Cancellation> Cancellations { get; set; }
}

public class Cancellation
{
    public Guid ID { get; set; }
    public DateTime Date { get; set; }
    public virtual PrivateLesson Lesson { get; set; }
    public virtual MakeUpLesson MakeUpLesson { get; set; }
}

public class MakeUpLesson : Lesson
{
    public DateTime Date { get; set; }
    public string Teacher { get; set; }
    public virtual Cancellation Cancellation { get; set; }
}

配置:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Lesson>().ToTable("Lessons");
    modelBuilder.Entity<RecurringLesson>().ToTable("RecurringLessons");
    modelBuilder.Entity<PrivateLesson>().ToTable("PrivateLessons");
    modelBuilder.Entity<MakeUpLesson>().ToTable("PrivateMakeUpLessons");

    modelBuilder.Entity<Cancellation>()
        .HasOptional(x => x.MakeUpLesson)
        .WithRequired(x => x.Cancellation);

    base.OnModelCreating(modelBuilder);
}

注意事项:

这在 EF 4.2 中运行良好。我的模型有问题吗?实际模型要复杂得多,这就是我将所有类抽象出来的原因。此外,我正在处理现有数据库,因此我需要使用 Table-Per-Type 继承。

如果我将 CancellationPrivateMakeUpLesson 的关系从 1 更改为 0..1 到 0..1 到 0..1,它就会起作用。这是不可取的,因为如果没有 Cancellation,您将无法拥有 PrivateMakeUpLesson

此外,如果我让 PrivateMakeUpLesson 不是从 Lesson 继承的,那么它也可以工作,但它是一个类(class),需要对现有的业务逻辑保持不变。

如有任何指导,我将不胜感激。谢谢!

编辑:

开始赏金。我找不到任何关于 EF 4.2 和 EF 4.3 之间关于代码优先索引生成的变化的文档。很明显,EF 4.3 正在创建更多索引并且命名方案已更改,但我想知道 EF 中是否存在错误,或者我的模型或 Fluent API 配置是否存在根本性错误。

最佳答案

从 EF 4.3 开始,在数据库创建期间为外部键列添加了索引。有一个错误会导致多次创建索引。这将在未来的 EF 版本中修复。

在那之前,您可以通过使用 Migrations 创建数据库来解决这个问题。而不是数据库初始化程序(或 Database.Create() 方法)。

生成初始迁移后,您需要删除对 Index() 的冗余调用。

CreateTable(
    "dbo.PrivateMakeUpLessons",
    c => new
        {
            ID = c.Guid(nullable: false),
            ...
        })
    .PrimaryKey(t => t.ID)
    .ForeignKey("dbo.Lessons", t => t.ID)
    .ForeignKey("dbo.Cancellations", t => t.ID)
    .Index(t => t.ID)
    .Index(t => t.ID); // <-- Remove this

要在运行时继续创建数据库,您可以使用 MigrateDatabaseToLatestVersion初始化程序。

关于c# - 升级到 Entity Framework 4.3.1 后未处理的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10441924/

相关文章:

c# - Unity 依赖注入(inject)(构造函数或属性)

c# - 采用 DateTimeOffset 的表达式导致 Visual Studio 内部编译器错误

entity-framework - 如果在服务中使用存储过程,OData 的优势是否会丧失?

asp.net-mvc - 路由 ID 覆盖 Model.Id

entity-framework - 如何在 EF 代码优先 4.3 中为 CreatedDate 列使用数据库默认值?

entity-framework - Entity Framework 迁移停止检测POCO更新

c# - 如何定义 EF code-first tri-way FK 关系? ( parent 有两个相关的 child )

c# - 在 C# 中查找接口(interface)索引

c# - 当变量在 C# 中定义匿名类时,如何在 block 外部声明变量

c# - 通过代码添加 Entity Framework 迁移