2012-07-24 13 views
23

मेरे पास इकाई फ्रेमवर्क कोड प्रथम दृष्टिकोण का उपयोग करके बनाई गई निम्न तालिका है।इकाई फ्रेमवर्क: टेबल से डिस्कमिनेटर कॉलम से कैसे बचें?

  1. मैं सी # कोड को कैसे संशोधित करूं ताकि अवांछित डिस्कमिनेटर कॉलम डेटाबेस में नहीं बनाया जा सके? क्या यह हासिल करने के लिए कोई विशेषता है?
  2. "भुगतान_ भुगतान आईडी" के बजाय विदेशी कुंजी कॉलम नाम को "भुगतान आईडी" के रूप में कैसे बनाया जाए? क्या यह हासिल करने के लिए कोई विशेषता है?

नोट: EntityFramework.dll के लिए रनटाइम संस्करण है v4.0.30XXX

enter image description here

कोड

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

} 

ग्राहक

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


     } 

    } 
+2

यदि आप सम्मेलनों को ओवरराइड करते हैं तो अन्य डेवलपर्स आपकी स्कीमा को समझने में संघर्ष करेंगे। सम्मेलनों को सीखना और उनका उपयोग करना अधिक फायदेमंद है, यानी आपको अन्य डेवलपर्स कोड या डिफ़ॉल्ट जेनरेट कोड पढ़ने पर प्रश्न पूछना नहीं होगा और आपको अतिरिक्त कोड भी लिखना पड़ेगा। – user3285954

उत्तर

29

टीपीएच विरासत को विशेष कॉलम की आवश्यकता होती है जिसका उपयोग इकाई के प्रकार की पहचान के लिए किया जाता है। डिफ़ॉल्ट रूप से इस कॉलम को Discriminator कहा जाता है और इसमें व्युत्पन्न इकाइयों के नाम होते हैं। आप अलग-अलग कॉलम नाम और विभिन्न मानों को परिभाषित करने के लिए फ़्लुएंट-एपीआई का उपयोग कर सकते हैं। आप सीधे अपने माईटाइप कॉलम का भी उपयोग कर सकते हैं क्योंकि यह वास्तव में एक भेदभावकर्ता है लेकिन ऐसे मामले में आपके पास उस इकाई में वह कॉलम नहीं हो सकता है (कॉलम केवल एक बार मैप किया जा सकता है और यदि आप इसे भेदभावकर्ता के रूप में उपयोग करते हैं तो इसे पहले ही मैपिंग के रूप में माना जाता है)।

विदेशी कुंजी स्तंभ का नाम फिर से सुविज्ञ-एपीआई के साथ नियंत्रित किया जा सकता है:

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")); 
} 
1

जैसा कि आप सबक्लास का उपयोग कर रहे हैं, डिस्कमिनेटर कॉलम को आपके प्रत्येक उप-वर्गों के बीच अंतर करने की आवश्यकता है।

0

चूंकि "गिफ्टकूपनपेमेंट" और "क्लबकार्डपेमेंट" दोनों "भुगतान कॉम्पोनेंट" से निकले हैं, इसलिए अलग-अलग तालिकाओं का उपयोग नहीं किया जाएगा और उस कॉलम की आवश्यकता होगी। यदि आप एक अलग व्यवहार चाहते हैं तो आपको डिफ़ॉल्ट तालिका पहुंच को ओवरराइड करना होगा और फ़ील्ड को अपनी कक्षाओं में मैप करना होगा (जो मुझे लगता है कि आप ऐसा नहीं करना चाहते हैं) सुनिश्चित नहीं है कि इसका कोई आसान तरीका है या नहीं। पहले इकाई से, मुझे पता है कि टेम्पलेट के माध्यम से एक तरीका है जो टेबल बनाता है।
विदेशी कुंजी कॉलम नाम के लिए भी यही है। ईएफ कुंजी/विदेशी नामों के नाम का निर्माण करने के उस तरीके का उपयोग करता है। यदि आप अपनी पसंद के अनुसार तालिका को प्रारूपित करना चाहते हैं, तो आपको इसे स्वयं करना होगा, जिससे सवाल उठता है कि ईएफ का उपयोग क्यों करें।
क्या सौंदर्य प्रसाधनों के अलावा, आप ऐसा करना चाहते हैं?

4

भी प्रकार (टीपीटी) प्रति तालिका का उपयोग किया जा सका।

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

टेबल प्रकार (टीपीटी) प्रति

टेबल प्रति प्रकार रिलेशनल विदेशी कुंजी संघों के रूप में विरासत रिश्तों का प्रतिनिधित्व करने के बारे में है। प्रत्येक वर्ग/सबक्लास जो निरंतर गुणों की घोषणा करता है-सार तत्वों सहित- इसकी अपनी तालिका है।उप-वर्गों के लिए तालिका में केवल प्रत्येक गैर-निहित संपत्ति (उप-वर्ग द्वारा घोषित प्रत्येक संपत्ति) के लिए कॉलम होते हैं प्राथमिक कुंजी के साथ जो बेस क्लास तालिका की एक विदेशी कुंजी भी है।

एफई कोड पहले में टीपीटी लागू

हम बस (मैप की तालिका नाम निर्दिष्ट करने के लिए टेबल विशेषता एक नया डेटा एनोटेशन और में जोड़ा गया है उपवर्गों पर तालिका विशेषता रखकर एक टीपीटी मैपिंग बनाते हैं ।

: CTP5 में System.ComponentModel.DataAnnotations नाम स्थान

आप धाराप्रवाह एपीआई पसंद करते हैं, तो आप एक टीपीटी मानचित्रण ToTable() विधि का उपयोग कर बना सकते हैं 0

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

ध्यान रखें कि प्रदर्शन एक मुद्दा होने पर ईएफ के लिए टीपीटी की अनुशंसा नहीं की जाती है। देखें: https://msdn.microsoft.com/en-US/data/hh949853 7.1.1 –

7

गुण जोड़ें [NotMapped] यदि संपत्ति कॉलम पर मैप करने के लिए नहीं जा रही है।

+2

के तहत, क्लास एट्रिब्यूट के रूप में [नोटमैपड] जोड़ना भी मदद करता है जब आप नहीं चाहते हैं कि ईएफ आपके उप-वर्गों को डेटाबेस टेबल पर मैप करें – kape123

+0

धन्यवाद - तुम, बिल्कुल जवाब मैं देख रहा था! – Jocie

+0

यदि आप विशेषता/एनोटेशन के बजाय फ़्लुएंट एपीआई का उपयोग करना पसंद करते हैं तो आप अपने _DbContext_ को संपादित कर सकते हैं और _OnModelCreating_ विधि में जोड़ सकते हैं: ** modelbuilder.Ignore (); ** – Rostov

0

डिस्कमिनेटर कॉलम को हटाने के लिए नमूना कोड और भुगतान आईडी नामक कॉलम को इसके बजाय भेदभावकर्ता के रूप में प्राप्त करें, इसलिए अपने दोनों प्रश्नों को हल करें। माइक्रोस्कोफ्ट फ्लुएंट एपी मूल दस्तावेज के आधार पर।

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

आदेश मेज से Discriminator स्तंभ से बचने के लिए आप बस अपने व्युत्पन्न वर्ग से अधिक एनोटेशन [NotMapped] जोड़ने की जरूरत है।

संबंधित मुद्दे