实体框架:如何避免表鉴别列? [英] Entity Framework: How to avoid Discriminator column from table?

查看:103
本文介绍了实体框架:如何避免表鉴别列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下表使用实体框架的代码首先的办法产生。




  1. 如何修改的C#代码,以便在数据库中未产生不必要的鉴别列?是否有任何属性来实现这一目标?

  2. 如何让外键列的名称为PaymentID而不是Payment_ PaymentID?是否有任何属性来实现这一



请注意:为EntityFramework.dll运行时版本的 v4.0.30XXX





代码

 公共抽象类PaymentComponent 
{
公众诠释PaymentComponentID {搞定;组; }
公众诠释myvalue的{搞定;组; }
公共字符串的MyType {搞定;组; }
公共抽象INT GetEffectiveValue();
}


公共部分类GiftCouponPayment:PaymentComponent
{

公共覆盖INT GetEffectiveValue()
{
如果(myvalue的< 2000)
{
返回0;
}
返回myvalue的;
}

}


公共部分类ClubCardPayment:PaymentComponent
{
公共覆盖INT GetEffectiveValue()
{
返回myvalue的;
}
}

公共部分类支付
{
公众诠释PaymentID {搞定;组; }
公开名单< PaymentComponent> PaymentComponents {搞定;组; }
公众的DateTime PayedTime {搞定;组; }

}



//System.Data.Entity.DbContext是EntityFramework.dll
公共类NerdDinners:系统。 Data.Entity.DbContext
{

公共NerdDinners(字符串CONNSTRING):基地(CONNSTRING)
{

}

保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
{
modelbuilder.Conventions.Remove< PluralizingTableNameConvention>();
}


公共DbSet< GiftCouponPayment> GiftCouponPayments {搞定;组; }
公共DbSet< ClubCardPayment> ClubCardPayments {搞定;组; }
公共DbSet<付款和GT;付款{搞定;组; }

}



客户端

 静态无效的主要(字串[] args)
{

字符串的ConnectionString =数据源= ;初始目录= NerdDinners;集成安全性= TRUE;连接超时= 30;使用

(VAR DB =新NerdDinners(的ConnectionString))
{

GiftCouponPayment giftCouponPayment =新GiftCouponPayment();
giftCouponPayment.MyValue = 250;
giftCouponPayment.MyType =GiftCouponPayment;

ClubCardPayment clubCardPayment =新ClubCardPayment();
clubCardPayment.MyValue = 5000;
clubCardPayment.MyType =ClubCardPayment;


名单,LT; PaymentComponent>谱曲=新的List< PaymentComponent>();
comps.Add(giftCouponPayment);
comps.Add(clubCardPayment);

变种支付=新的付款{PaymentComponents =谱曲,PayedTime = DateTime.Now};
db.Payments.Add(付款);

INT recordsAffected = db.SaveChanges();


}

}


解决方案

TPH继承需要用来识别实体的类型的特殊列。默认情况下此列名为并包含派生实体的名字。你可以用流利的API定义不同的列名和不同的价值观。您也可以直接使用您的MyType列,因为它实际上是一个鉴别,但在这种情况下,你不能在你的实体列(列只能进行一次映射,如果你使用它作为鉴别它已经被视为映射)。



外键列的名称可以用流利的API再次控制:

 保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
{
modelbuilder.Conventions.Remove< PluralizingTableNameConvention>();

//控制TPH iheritance的例子:
modelBuilder.Entity< PaymentComponent>()
.MAP< GiftPaymentComponent>(M => m.Requires(的MyType) .HasValue(G))
.MAP&所述; ClubPaymentComponent方式>(M => m.Requires(的MyType)的HasValue(C));

//例控制外键:
modelBuilder.Entity<付款及GT;()
.HasMany(P => p.PaymentComponents)
.WithRequired( )
.MAP(M = GT; m.MapKey(PaymentId));
}


I have following table created using Entity Framework Code First approach.

  1. How do I modify the C# code so that the unwanted Discriminator column is not created in database? Is there any attributes to achieve that?
  2. How to make the foreign key column name as "PaymentID" instead of "Payment_ PaymentID"? Is there any attributes to achieve that?

Note: Runtime version for EntityFramework.dll is v4.0.30XXX

CODE

public abstract class PaymentComponent
{
    public int PaymentComponentID { get; set; }
    public int MyValue { get; set; }
    public string MyType { 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; }

}



//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)
    {
        modelbuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }


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

}

CLIENT

    static void Main(string[] args)
    {

        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;
            giftCouponPayment.MyType = "GiftCouponPayment";

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


            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();


        }

    }

解决方案

TPH inheritance needs special column which is used to identify the type of entity. By default this column is called Discriminator and contains names of derived entities. You can use Fluent-API to define different column name and different values. You can also use your MyType column directly because it is actually a discriminator but in such case you cannot have that column in your entity (column can be mapped only once and if you use it as discriminator it is already considered as mapping).

The name of foreign key column can be again controlled with Fluent-API:

protected override void OnModelCreating(DbModelBuilder modelbuilder)
{
    modelbuilder.Conventions.Remove<PluralizingTableNameConvention>();

    // Example of controlling TPH iheritance:
    modelBuilder.Entity<PaymentComponent>()
            .Map<GiftPaymentComponent>(m => m.Requires("MyType").HasValue("G"))
            .Map<ClubPaymentComponent>(m => m.Requires("MyType").HasValue("C"));

    // Example of controlling Foreign key:
    modelBuilder.Entity<Payment>()
                .HasMany(p => p.PaymentComponents)
                .WithRequired()
                .Map(m => m.MapKey("PaymentId"));
}

这篇关于实体框架:如何避免表鉴别列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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