使用抽象类和流畅的api时错放了外键

时间:2011-10-20 11:21:16

标签: entity-framework entity-framework-4.1 ef-code-first fluent-interface

我在使用抽象类时将外键映射到正确的表时遇到问题。这是我的模特:

public abstract class Entity
{
    public Guid UID { get; set; }
}

public abstract class Product : Entity
{
    public DeviceModel Model { get; set; }
    public User Operator { get; set; }
}

public abstract class OrderEntry : Entity
{
    public Order Order { get; set; }
}

public class Device : Product
{
    public String Reference { get; set; }
    public String Serial { get; set; }
    public String SoftwareVersion { get; set; }
}

public class OrderEntryDevice : OrderEntry
{
    public DeviceModel Model { get; set; }
}

流畅的api配置(TPT架构):

public class EntityConfiguration : EntityTypeConfiguration<Entity>
{
    public EntityConfiguration()
    {
        ToTable("Entities");

        HasKey(t => t.UID);
    }
}

public class ProductConfiguration : EntityTypeConfiguration<Product>
{
    public ProductConfiguration()
    {
        ToTable("Products");

        HasOptional(t => t.Operator)
            .WithMany()
            .Map(t => t.MapKey("FK_Operator"))
            .WillCascadeOnDelete(false);
    }
}

public class OrderEntryConfiguration : EntityTypeConfiguration<OrderEntry>
{
    public OrderEntryConfiguration()
    {
        ToTable("OrderEntries");

        HasRequired(t => t.Order)
            .WithMany()
            .Map(t => t.MapKey("FK_Order"))
            .WillCascadeOnDelete(false);
    }
}

public class DeviceConfiguration : EntityTypeConfiguration<Device>
{
    public DeviceConfiguration()
    {
        ToTable("Devices");

        Property(t => t.Reference)
            .IsRequired();

        Property(t => t.Serial)
            .IsRequired();

        HasRequired(t => t.Model)
            .WithMany()
            .Map(t => t.MapKey("FK_Model"))
            .WillCascadeOnDelete(false);
    }
}

public class OrderEntryDeviceConfiguration : EntityTypeConfiguration<OrderEntryDevice>
{
    public OrderEntryDeviceConfiguration()
    {
        ToTable("OrderEntriesDevice");

        HasRequired(t => t.Model)
            .WithMany()
            .Map(t => t.MapKey("FK_Model"))
            .WillCascadeOnDelete(false);
    }
}

创建数据库会将“FK_Operator”外键放在“Products”表中(正好在我想要的位置),但“FK_Order”外键放在“Entities”表而不是“OrderEntries”表中。如果我将类“OrderEntry”的抽象属性更改为具体,那么一切都OK。在这种情况下我是否必须避免抽象类int?

1 个答案:

答案 0 :(得分:0)

我已经尝试过你的模型,我无法重现这个问题。我得到了FK_Order表格中的OrderEntries列,而不是Entities表格中的Program.cs列。

您可以将以下内容复制到控制台应用的EntityFramework.dll中(同时将System.ComponentModel.DataAnnotations.dllUser添加到参考中)。

我为DeviceModelOrderusing System; using System.Linq; using System.Data.Entity.ModelConfiguration; using System.Data.Entity; using System.ComponentModel.DataAnnotations; namespace EFAbstractTest { public class User { [Key] public Guid UID { get; set; } public string Name { get; set; } } public class DeviceModel { [Key] public Guid UID { get; set; } public string Name { get; set; } } public class Order { [Key] public Guid UID { get; set; } public string Name { get; set; } } public abstract class Entity { public Guid UID { get; set; } } public abstract class Product : Entity { public DeviceModel Model { get; set; } public User Operator { get; set; } } public abstract class OrderEntry : Entity { public Order Order { get; set; } } public class Device : Product { public String Reference { get; set; } public String Serial { get; set; } public String SoftwareVersion { get; set; } } public class OrderEntryDevice : OrderEntry { public DeviceModel Model { get; set; } } public class EntityConfiguration : EntityTypeConfiguration<Entity> { public EntityConfiguration() { ToTable("Entities"); HasKey(t => t.UID); } } public class ProductConfiguration : EntityTypeConfiguration<Product> { public ProductConfiguration() { ToTable("Products"); HasOptional(t => t.Operator) .WithMany() .Map(t => t.MapKey("FK_Operator")) .WillCascadeOnDelete(false); } } public class OrderEntryConfiguration : EntityTypeConfiguration<OrderEntry> { public OrderEntryConfiguration() { ToTable("OrderEntries"); HasRequired(t => t.Order) .WithMany() .Map(t => t.MapKey("FK_Order")) .WillCascadeOnDelete(false); } } public class DeviceConfiguration : EntityTypeConfiguration<Device> { public DeviceConfiguration() { ToTable("Devices"); Property(t => t.Reference) .IsRequired(); Property(t => t.Serial) .IsRequired(); HasRequired(t => t.Model) .WithMany() .Map(t => t.MapKey("FK_Model")) .WillCascadeOnDelete(false); } } public class OrderEntryDeviceConfiguration : EntityTypeConfiguration<OrderEntryDevice> { public OrderEntryDeviceConfiguration() { ToTable("OrderEntriesDevice"); HasRequired(t => t.Model) .WithMany() .Map(t => t.MapKey("FK_Model")) .WillCascadeOnDelete(false); } } public class MyContext : DbContext { public DbSet<Entity> Entities { get; set; } public DbSet<User> Users { get; set; } public DbSet<DeviceModel> DeviceModels { get; set; } public DbSet<Order> Orders { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new EntityConfiguration()); modelBuilder.Configurations.Add(new ProductConfiguration()); modelBuilder.Configurations.Add(new OrderEntryConfiguration()); modelBuilder.Configurations.Add(new DeviceConfiguration()); modelBuilder.Configurations.Add(new OrderEntryDeviceConfiguration()); } } class Program { static void Main(string[] args) { using (var ctx = new MyContext()) { // some query, just to trigger database creation ctx.Orders.Count(); } } } } 创建了三个虚拟类,以便编译和运行代码。但是其他课程都是你问题的副本。

问题是:下面的代码与您的代码之间的重要区别在哪里可能会导致错误的映射?

{{1}}