Entity framework 使用抽象类和fluent api时外键放置错误
使用抽象类时,我在将外键映射到正确的表时遇到问题。这是我的模型:Entity framework 使用抽象类和fluent api时外键放置错误,entity-framework,entity-framework-4.1,ef-code-first,fluent-interface,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 O
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; }
}
以及fluent api配置(TPT模式):
公共类EntityConfiguration:EntityTypeConfiguration
{
公共实体配置()
{
可转让(“实体”);
HasKey(t=>t.UID);
}
}
公共类ProductConfiguration:EntityTypeConfiguration
{
公共产品配置()
{
ToTable(“产品”);
has可选(t=>t.Operator)
.有很多
.Map(t=>t.MapKey(“FK_运算符”))
.WillCascadeOnDelete(假);
}
}
公共类OrderEntryConfiguration:EntityTypeConfiguration
{
public OrderEntryConfiguration()
{
ToTable(“订单条目”);
HasRequired(t=>t.Order)
.有很多
.Map(t=>t.MapKey(“FK_顺序”))
.WillCascadeOnDelete(假);
}
}
公共类设备配置:EntityTypeConfiguration
{
公共设备配置()
{
可折叠(“装置”);
属性(t=>t.Reference)
.IsRequired();
属性(t=>t.Serial)
.IsRequired();
HasRequired(t=>t.Model)
.有很多
.Map(t=>t.MapKey(“FK_模型”))
.WillCascadeOnDelete(假);
}
}
公共类OrderEntryDeviceConfiguration:EntityTypeConfiguration
{
public OrderEntryDeviceConfiguration()
{
ToTable(“OrderEntriesDevice”);
HasRequired(t=>t.Model)
.有很多
.Map(t=>t.MapKey(“FK_模型”))
.WillCascadeOnDelete(假);
}
}
创建数据库将把“FK_运算符”外键放在“Products”表中(正好在我想要的位置),但“FK_Order”外键放在“Entities”表中,而不是“OrderEntries”表中。如果我将类“OrderEntry”的抽象属性更改为具体属性,那么一切都正常。在这种情况下,我必须避免抽象类吗?我已经尝试过你的模型,但我无法重现这个问题。我在
OrderEntries
表中获得了FK_Order
列,而不是在Entities
表中,这与预期一致
您可以将以下内容复制到控制台应用程序的Program.cs
(还可以将EntityFramework.dll
和System.ComponentModel.DataAnnotations.dll
添加到引用中)
我已经为User
、DeviceModel
和Order
创建了三个虚拟类来编译和运行代码。但其他课程都是你问题的翻版
问题是:下面的代码和您的代码之间的重要区别在哪里,这可能会导致错误的映射
using 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();
}
}
}
}
使用系统;
使用System.Linq;
使用System.Data.Entity.ModelConfiguration;
使用System.Data.Entity;
使用System.ComponentModel.DataAnnotations;
命名空间EFAbstractTest
{
公共类用户
{
[关键]
公共Guid UID{get;set;}
公共字符串名称{get;set;}
}
公共类设备模型
{
[关键]
公共Guid UID{get;set;}
公共字符串名称{get;set;}
}
公共阶级秩序
{
[关键]
公共Guid UID{get;set;}
公共字符串名称{get;set;}
}
公共抽象类实体
{
公共Guid UID{get;set;}
}
公共抽象类产品:实体
{
公共设备模型{get;set;}
公共用户运算符{get;set;}
}
公共抽象类OrderEntry:实体
{
公共秩序{get;set;}
}
公共类设备:产品
{
公共字符串引用{get;set;}
公共字符串序列{get;set;}
公共字符串软件版本{get;set;}
}
公共类OrderEntryDevice:OrderEntry
{
公共设备模型{get;set;}
}
公共类EntityConfiguration:EntityTypeConfiguration
{
公共实体配置()
{
可转让(“实体”);
HasKey(t=>t.UID);
}
}
公共类ProductConfiguration:EntityTypeConfiguration
{
公共产品配置()
{
ToTable(“产品”);
has可选(t=>t.Operator)
.有很多
.Map(t=>t.MapKey(“FK_运算符”))
.WillCascadeOnDelete(假);
}
}
公共类OrderEntryConfiguration:EntityTypeConfiguration
{
public OrderEntryConfiguration()
{
ToTable(“订单条目”);
HasRequired(t=>t.Order)
.有很多
.Map(t=>t.MapKey(“FK_顺序”))
.WillCascadeOnDelete(假);
}
}
公共类设备配置:EntityTypeConfiguration
{
公共设备配置()
{
可折叠(“装置”);
属性(t=>t.Reference)
.IsRequired();
属性(t=>t.Serial)
.IsRequired();
HasRequired(t=>t.Model)
.有很多
.Map(t=>t.MapKey(“FK_模型”))
.WillCascadeOnDelete(假);
}
}
公共类OrderEntryDeviceConfiguration:EntityTypeConfiguration
{
public OrderEntryDeviceConfiguration()
{
ToTable(“OrderEntriesDevice”);
HasRequired(t=>t.Model)
.有很多
.Map(t=>t.MapKey(“FK_模型”))
.WillCascadeOnDelete(假);
}
}
公共类MyContext:DbContext
{
公共数据库集实体{get;set;}
公共数据库集用户{get;set;}
公共数据库集设备模型{get;set;}
公共数据库集命令{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
模型建筑
using 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();
}
}
}
}