web-gelistirme-sc.com

Varlık Çerçevesi: Discriminator sütununu tablodan nasıl uzak tutabilirim?

Entity Framework Kod İlk yaklaşımı kullanılarak oluşturulan aşağıdaki tabloyu hazırladım. 

  1. İstenmeyen Discriminator sütunu veritabanında oluşturulmayacak şekilde C # kodunu nasıl değiştiririm? Bunu başarmak için herhangi bir özellik var mı?
  2. Yabancı anahtar sütun adını “Payment_ PaymentID” yerine “PaymentID” olarak nasıl yapabilirim? Bunu başarmak için herhangi bir özellik var mı?

Not: EntityFramework.dll dosyasının çalışma zamanı sürümü v4.0.30XXX

enter image description here

KODU

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; }

}

M&UUML;ŞTERI

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


        }

    }
26
Lijo

TPH devralma, varlığın türünü tanımlamak için kullanılan özel bir sütuna ihtiyaç duyar. Varsayılan olarak bu sütuna Discriminator adı verilir ve türetilmiş varlıkların adlarını içerir. Farklı sütun adı ve farklı değerler tanımlamak için Fluent-API kullanabilirsiniz. Ayrıca, MyType sütununuzu doğrudan bir ayırıcı olduğu için doğrudan kullanabilirsiniz, ancak bu durumda varlığınızda bu sütunu kullanamazsınız (sütun yalnızca bir kez eşlenebilir ve ayırıcı olarak kullanıyorsanız zaten haritalama olarak kabul edilir).

Yabancı anahtar sütununun adı Fluent-API ile tekrar kontrol edilebilir:

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"));
}
30
Ladislav Mrnka

Özellik sütuna eşlenmezse [NotMapped] özelliğini ekleyin.

8
John Li

Ayrıca Tür başına Tablo (TPT) kullanabilir.

http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt

Tip başına Tablo (TPT)

Tür başına tablo, miras ilişkilerini .__ olarak göstermektedir. ilişkisel yabancı anahtar dernekleri. Her sınıf/alt sınıf that soyut sınıflar da dahil olmak üzere kalıcı özellikler ilan eder. tablo. Alt sınıflar için tablo yalnızca her .__ için sütunlar içerir. miras alınmamış mallar (alt sınıfın kendisi tarafından ilan edilen her mal). Ayrıca temel sınıfın yabancı bir anahtarı olan bir birincil anahtar ile birlikte tablo.

Önce TP Kodunda TPT Uygula

Sadece bir TPT haritası oluşturabiliriz. eşlenmiş tablo adını belirtmek için alt sınıflar (Tablo özelliği yeni bir veri ek açıklamasıdır ve CTP5'teki System.ComponentModel.DataAnnotations ad alanına eklenmiştir.

Akıcı API'yi tercih ediyorsanız, .__ kullanarak bir TPT eşlemesi oluşturabilirsiniz. ToTable () yöntemi:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<BankAccount>().ToTable("BankAccounts");
    modelBuilder.Entity<CreditCard>().ToTable("CreditCards");
}
3
user3285954

Alt sınıfları kullanırken, alt sınıflarınızın her türünü ayırt etmek için Discriminator sütunu gerekir.

1
mathieu

Hem "GiftCouponPayment" hem de "ClubCardPayment", "PaymentComponent" ten geldiğinden, ayrı tablolar kullanmayacak ve bu sütuna ihtiyaç duyacak. Farklı bir davranış istiyorsanız, varsayılan tablo erişimini geçersiz kılmanız ve alanları sınıflarınızla eşleştirmeniz gerekir (ki bunu yapmak istemediğinizi düşünüyorum). Bunun kolay bir yolu olup olmadığından emin değilsiniz. İlk önce varlıktan, tabloları oluşturan şablonun bir yolu olduğunu biliyorum. 
Aynı yabancı anahtar sütun adı için. EF, anahtar/yabancı anahtar adları için ad oluşturma yöntemini kullanır. Eğer tabloyu istediğiniz gibi biçimlendirmek istiyorsanız, hepsini kendiniz yapmak zorundasınız, bu da neden EF kullandığını sorguluyor.
Bunu kozmetikten başka yapmak istemenin özel bir nedeni var mı?

0
DerApe

Discriminator sütununu tablodan korumak için türetilmiş sınıfınıza not eklemeniz yeterlidir.

0
Valeriy

Discriminator sütununu kaldırmak ve PaymentId adlı sütunu ayırıcı olarak almak için örnek kod kullanın, bu nedenle her iki sorunuzu da çözebilirsiniz. Microsofts Fluent Api orijinal belgelerine dayanarak.

https://msdn.Microsoft.com/en-us/library/jj591617%28v=vs.113%29.aspx?f=255&MSPPError=-2147217396

public enum MyEnum
{ 
    Value1, Value2
}

public class MyBaseClass

{ 
    [NotMapped]
    public MyEnum PaymentId { get; protected set; }
}

public class DerivedOne: MyBaseClass
{
    public DerivedOne()
    {
        PaymentId = MyEnum.Value1;
    } 
}

public class DerivedTwo: MyBaseClass
{
    public DerivedTwo()
    {
        PaymentId = MyEnum.Value2;
    }
}

public class MyDbContext : DbContext
{
    DbSet<MyBaseClass> MyBaseClass { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<MyBaseClass>()
            .Map<DerivedOne>(x => x.Requires("PaymentId").HasValue((int)PaymentId.Value1))
            .Map<DerivedTwo>(x => x.Requires("PaymentId").HasValue((int)PaymentId.Value2));
    }
}
0
Ogglas