继承使用EF代码优先

继承使用EF代码优先

本文介绍了主要违规:继承使用EF代码优先的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的EF代码第一个代码。我收到以下异常:

参考



注意:生成的数据库模式如下所示。 p>



代码:

  public class MyInitializer:CreateDatabaseIfNotExists< NerdDinners> 
{
//每个表只能创建一个标识列。
protected override void Seed(NerdDinners context)
{
//context.Database.ExecuteSqlCommand(\"CREATE UNIQUE INDEX IX_Payment_PayedTime ON Payment(PayedTime));
context.Database.ExecuteSqlCommand(DBCC CHECKIDENT('Payment',RESEED,1));
context.Database.ExecuteSqlCommand(DBCC CHECKIDENT('GiftCouponPayment',RESEED,2));
context.Database.ExecuteSqlCommand(DBCC CHECKIDENT('ClubCardPayment',RESEED,3));
}
}

//System.Data.Entity.DbContext来自EntityFramework.dll
public class NerdDinners:System.Data.Entity.DbContext
{
public NerdDinners(string connString):base(connString)
{
}

protected override void OnModelCreating(DbModelBuilder modelbuilder)
{
//流利的API - 多重删除
modelbuilder.Conventions.Remove< PluralizingTableNameConvention>();

//流利的API - 每个混合类型表(TPC)
modelbuilder.Entity< GiftCouponPayment>()
.Map(m =>
{
m.MapInheritedProperties();
m.ToTable(GiftCouponPayment);
});

modelbuilder.Entity< ClubCardPayment>()
.Map(m =>
{
m.MapInheritedProperties();
m.ToTable ClubCardPayment);
});
}

public DbSet< GiftCouponPayment> GiftCouponPayments {get;组; }
public DbSet&ClubCardPayment> ClubCardPayments {get;组; }
public DbSet< Payment>付款{get;组; }
}

public abstract class PaymentComponent
{
public int PaymentComponentID {get;组; }
public int MyValue {get;组; }
public abstract int GetEffectiveValue();


public partial class GiftCouponPayment:PaymentComponent
{
public override int GetEffectiveValue()
{
if(MyValue< 2000)
{
return 0;
}
返回MyValue;
}
}

公共部分类ClubCard付款:PaymentComponent
{
public override int GetEffectiveValue()
{
return MyValue ;
}
}

public partial class付款
{
public int PaymentID {get;组; }
public List< PaymentComponent> PaymentComponents {get;组; }
public DateTime PayedTime {get;组; }
}

客户端:

  static void Main(string [] args)
{
Database.SetInitializer< NerdDinners>(new MyInitializer());
string connectionstring =Data Source =; Initial Catalog = NerdDinners; Integrated Security = True; Connect Timeout = 30;

使用(var db = new NerdDinners(connectionstring))
{
GiftCouponPayment giftCouponPayment = new GiftCouponPayment();
giftCouponPayment.MyValue = 250;

ClubCard付款clubCardPayment =新的ClubCard付款();
clubCardPayment.MyValue = 5000;

列表< PaymentComponent> comps = new List< PaymentComponent>();
comps.Add(giftCouponPayment);
comps.Add(clubCardPayment);

var payment = new Payment {PaymentComponents = comps,PayedTime = DateTime.Now};
db.Payments.Add(付款);

int recordsAffected = db.SaveChanges();
}
}


解决方案

看到我对TPC的初步建议是不正确的,因为你也在基类中使用FK - 你看到 PaymentComponent 表?在TPC继承的情况下不应该是。尝试使用TPT继承(从映射中删除 MapInheritedProperties )。这将以相同的正确数据库结束。不要使用杂草该ID将仅由 PaymentComponent 表中的标识列(目前为止)进行控制。


I have following EF code first code. I am getting the following exception:

The tables are successfully created in database. However, how can I get rid of this exception? Also, what is the reason for this exception?

Note: I am okay with any table schema as longs as the domain model (described using code first) is retained (and the data can be queried).

After continuing this exception, there is a another exception as below:

Reference:

  1. Entity Framework: Split table into multiple tables

Note: The resulting database schema is as shown below.

Code:

public class MyInitializer : CreateDatabaseIfNotExists<NerdDinners>
{
    //Only one identity column can be created per table.
    protected override void Seed(NerdDinners context)
    {
        //context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX IX_Payment_PayedTime ON Payment (PayedTime)");
        context.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('Payment', RESEED, 1)");
        context.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('GiftCouponPayment', RESEED, 2)");
        context.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('ClubCardPayment', RESEED, 3)");
    }
}

//System.Data.Entity.DbContext is from EntityFramework.dll
public class NerdDinners : System.Data.Entity.DbContext
{
    public NerdDinners(string connString): base(connString)
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelbuilder)
    {
        //Fluent API - Plural Removal
        modelbuilder.Conventions.Remove<PluralizingTableNameConvention>();

        //Fluent API - Table per Concrete Type (TPC)
        modelbuilder.Entity<GiftCouponPayment>()
            .Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("GiftCouponPayment");
            });

        modelbuilder.Entity<ClubCardPayment>()
            .Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("ClubCardPayment");
            });
    }

    public DbSet<GiftCouponPayment> GiftCouponPayments { get; set; }
    public DbSet<ClubCardPayment> ClubCardPayments { get; set; }
    public DbSet<Payment> Payments { get; set; }
}

public abstract class PaymentComponent
{
    public int PaymentComponentID { get; set; }
    public int MyValue { get; set; }
    public abstract int GetEffectiveValue();
}

public partial class GiftCouponPayment : PaymentComponent
{
    public override int GetEffectiveValue()
    {
        if (MyValue < 2000)
        {
            return 0;
        }
        return MyValue;
    }
}

public partial class ClubCardPayment : PaymentComponent
{
    public override int GetEffectiveValue()
    {
        return MyValue;
    }
}

public partial class Payment
{
    public int PaymentID { get; set; }
    public List<PaymentComponent> PaymentComponents { get; set; }
    public DateTime PayedTime { get; set; }
}

Client:

    static void Main(string[] args)
    {
        Database.SetInitializer<NerdDinners>(new MyInitializer());
        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";

        using (var db = new NerdDinners(connectionstring))
        {
            GiftCouponPayment giftCouponPayment = new GiftCouponPayment();
            giftCouponPayment.MyValue=250;

            ClubCardPayment clubCardPayment = new ClubCardPayment();
            clubCardPayment.MyValue = 5000;

            List<PaymentComponent> comps = new List<PaymentComponent>();
            comps.Add(giftCouponPayment);
            comps.Add(clubCardPayment);

            var payment = new Payment { PaymentComponents = comps, PayedTime=DateTime.Now };
            db.Payments.Add(payment);

            int recordsAffected = db.SaveChanges();
        }
    }
解决方案

I see that my initial advice about TPC wasn't correct because you are also using FK in the base class - do you see the PaymentComponent table? It should not be there in case of TPC inheritance. Try to use TPT inheritance (remove MapInheritedProperties from your mapping). This will end with the same correct database. Don't use reseed. The Id will be controlled just by identity column in PaymentComponent table (as it is at the moment).

这篇关于主要违规:继承使用EF代码优先的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 10:05