我有以下类结构:
如何配置 Fluent API 以将识别关系放入 Cards 表中?
我是说
- 卡片表 PK:Id、CustomerId
- 卡片表 FK:CustomerId
当我为 Customer.Card 属性分配新卡时,我希望删除以前的卡。
所以我这样定义我的类:
public class Customer
{
public int Id { get; private set; }
public virtual Card Card { get; set; }
}
public abstract class Card
{
public int Id { get; private set; }
}
public class Visa : Card
{
}
public class Amex : Card
{
}
DbContext 看起来像这样:
public class Context : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Card> Cards { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Customer>()
.HasRequired(c => c.Card)
.WithRequiredPrincipal()
.Map(a => a.MapKey("CustomerId"))
.WillCascadeOnDelete();
modelBuilder.Entity<Card>();
}
}
这是测试:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var context = new Context();
var customer = new Customer();
context.Customers.Add(customer);
customer.Card = new Visa();
context.SaveChanges();
customer.Card = new Amex();
context.SaveChanges();
Assert.AreEqual(1, context.Customers.Count());
Assert.AreEqual(1, context.Cards.Count());
}
}
它根本不起作用。我在第二次保存时有这个,我不知道如何在这里指定识别关系:
未处理的异常:System.Data.Entity.Infrastructure.DbUpdateException:保存不为其关系公开外键属性的实体时发生错误或发生。EntityEntries 属性将返回 null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常离子。有关详细信息,请参阅 InnerException。---> System.Data.Entity.Core.UpdateException:来自“Customer_Card”关联集的关系处于“已删除”状态。给定多重约束,相应的“Customer_Card _Target”也必须处于“已删除”状态。
更新很容易让它适用于一对多的关系。您可以在下面找到一个完整的示例:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var context = new Context();
var customer = new Customer();
context.Customers.Add(customer);
customer.Cards.Add(new Visa());
context.SaveChanges();
customer.Cards[0] = new Amex();
context.SaveChanges();
Assert.AreEqual(1, context.Cards.Count());
}
}
public class Customer
{
public Customer()
{
Cards = new List<Card>();
}
public int Id { get; private set; }
public virtual List<Card> Cards { get; set; }
}
public abstract class Card
{
public int Id { get; private set; }
public int CustomerId { get; private set; }
}
public class Visa : Card
{
}
public class Amex : Card
{
}
public class Context : DbContext
{
static Context()
{
Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
}
public DbSet<Customer> Customers { get; set; }
public DbSet<Card> Cards { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Customer>()
.HasMany(c => c.Cards)
.WithRequired()
.HasForeignKey(c => c.CustomerId)
.WillCascadeOnDelete();
modelBuilder.Entity<Card>()
.HasKey(c => new { c.Id, c.CustomerId });
}
}