升级到实体框架后未处理的异常4.3.1 [英] Unhandled Exception after Upgrading to Entity Framework 4.3.1

查看:95
本文介绍了升级到实体框架后未处理的异常4.3.1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

错误:

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

Unhandled Exception: System.Data.SqlClient.SqlException: The operation failed because an index or statistics with name 'IX_ID' already exists on table 'PrivateMakeUpLessons'.

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

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继承。

This worked fine in EF 4.2. Is there something wrong with my model? The actual model is much more complicated which is why I have all the classes abstracted out. Also, I am working against an existing database so I need to use Table-Per-Type inheritance.

如果我更改了取消的关系 PrivateMakeUpLesson 从1到0..1到0..1到0..1它可以工作。这是不可取的,因为您不能拥有 PrivateMakeUpLesson 而没有取消

If I change the relationship of Cancellation to PrivateMakeUpLesson from 1 to 0..1 to 0..1 to 0..1 it works. This is undesirable because you can't have a PrivateMakeUpLesson without a Cancellation.

另外,如果我使 PrivateMakeUpLesson 不继承 Lesson 那么它也可以工作,但它是一个教训,需要保持现有的业务逻辑。

Also, if I make PrivateMakeUpLesson NOT inherit from Lesson then it also works, but it IS a lesson and needs to remain so for existing business logic.

我很感激任何指导。谢谢!

I'd appreciate any guidance. Thank you!

修改

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

Starting a bounty. I can't find any documentation on what changed between EF 4.2 and EF 4.3 with regard to the index generation for code first. It's clear that EF 4.3 is creating more indexes and that the naming scheme has changed but I want to know if there's a bug in EF or if there is something fundamentally wrong with my model or fluent API configuration.

推荐答案

从EF 4.3起,在数据库创建过程中为freign键列添加索引。有一个错误可能导致不止一次创建索引。这将在未来的EF版本中修复。

As of EF 4.3, indexes are added for freign key columns during database creation. There is a bug that can cause an index to be created more than once. This will be fixed in a future EF release.

在此之前,您可以通过使用迁移,而不是数据库初始化程序(或 Database.Create()方法)。

Until then, you can work around the issue by creating your database using Migrations instead of database initializers (or the Database.Create() method).

生成初始迁移后,您需要删除冗余呼叫到 Index()

After generating the initial migration, you will need to delete the redundant call to 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 初始化程序。

To continue creating your database at run-time, you can use the MigrateDatabaseToLatestVersion initializer.

这篇关于升级到实体框架后未处理的异常4.3.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆