6

के संपर्क में न मैं User और Person संस्थाओं, ऐसी है कि प्रत्येक User वास्तव में 1 Person से जुड़ा होना चाहिए, और प्रत्येक Person शून्य या 1 User संबद्ध किया जा सकता के साथ एक इकाई मॉडल है।DbUpdateException है कि विदेशी कुंजी गुण

User (0..1) <-------> (1) Person 

एसोसिएशन को धीरे-धीरे मैप किया गया है।

private class PersonOrm : EntityTypeConfiguration<Person> 
{ 
    internal PersonOrm() 
    { 
     ToTable(typeof(Person).Name, DbSchemaName.People); 

     // has zero or one User 
     HasOptional(p => p.User) 
      .WithRequired(d => d.Person) 
      .Map(d => d.MapKey("PersonId")) 
      .WillCascadeOnDelete(false) 
     ; 

जब से मैं इस त्रुटि का सामना करना पड़ा, मैं भी यही मानचित्रण User ओर करने के लिए कहा::

private class UserOrm : EntityTypeConfiguration<User> 
{ 
    internal UserOrm() 
    { 
     ToTable(typeof(User).Name, DbSchemaName.Identity); 

     // has exactly 1 Person 
     HasRequired(p => p.Person) 
      .WithOptional(d => d.User) 
      .Map(d => d.MapKey("PersonId")) 
      .WillCascadeOnDelete(false); 

आवेदन जहां में एक परिदृश्य नहीं है मूल रूप से मैं केवल यह Person पक्ष पर घोषित की थी एक नया User बनाया जा सकता है और मौजूदा Person से जुड़ा हुआ है। यह वह जगह है जहां मुझे इस समय कठिनाई हो रही है। ईएफ User पर रिश्ते के आश्रित पक्ष के रूप में विचार कर रहा है, और User तालिका पर PersonId (FK, int, not null) कॉलम डाल रहा है। मुझे विश्वास नहीं है कि ईएफ को एसोसिएशन का प्रबंधन करने में मदद करने के लिए किसी भी इकाई पर विदेशी कुंजी संपत्ति का उपयोग करना संभव है (है ना?)।

// find out if Person already exists 
var person = context.People.SingleOrDefault(p => p.Emails.Any(
    e => e.Value.Equals(emailAddress, StringComparison.OrdinalIgnoreCase))); 

// find out if User already exists 
var user = context.Users.SingleOrDefault(
    u => u.Name.Equals(emailAddress, StringComparison.OrdinalIgnoreCase)); 

if (user == null) 
{ 
    user = new User 
    { 
     Name = emailAddress, 
     IsRegistered = isRegistered, 
     Person = person ?? PersonFactory.Create(emailAddress), 
     // ignore the PersonFactory.Create, that part works 
    }; 

    context.Entry(user).State = EntityState.Added; 
    context.SaveChanges(); 
} 

इस कोड को ठीक काम करता है जब person रिक्त है (पहले से ही DB में मौजूद नहीं है):

यहाँ कुछ ऐसा न करने पर कोड परिदृश्य को संभालने के लिए कोशिश करता है। हालांकि जब person शून्य नहीं है (डीबी में पहले से मौजूद है) और user शून्य है, तो कोड एक नया User बनाने का प्रयास करता है और इसे मौजूदा Person से संबद्ध करता है।

जबकि संस्थाओं है कि अपने संबंधों के लिए विदेशी कुंजी गुण के संपर्क में न सहेजने में त्रुटि आई: जब SaveChanges() लागू, मैं एक DbUpdateException मिलता है। EntityEntries प्रॉपर्टी वापसी शून्य होगी क्योंकि एक इकाई को अपवाद के स्रोत के रूप में पहचाना नहीं जा सकता है। बचत करते समय अपवादों को संभालना आपके इकाई प्रकारों में विदेशी कुंजी गुणों को उजागर करके आसान बनाया जा सकता है। विवरण के लिए इनर एक्सेप्शन देखें।

भीतरी अपवाद है:

'User_Person' AssociationSet से एक रिश्ता 'हटाया गया' स्थिति में है। बहुगुणित बाधाओं को देखते हुए, संबंधित 'User_Person_Source' को 'हटाए गए' राज्य में भी होना चाहिए।

इसका कारण यह है मैं कुछ भी नष्ट करने की कोशिश नहीं कर रहा हूँ, और दोनों User और Person की EntityState जाँच मेरे लिए कोई मतलब नहीं है पता चलता है कि UserAdded राज्य में है, जबकि PersonUnchanged अवस्था में है । मैं SaveChanges() अधिरोहित है प्रदर्शित करने के लिए:

public override int SaveChanges() 
{ 
    var userChanges = ChangeTracker.Entries<User>().Single(); 
    var personChanges = ChangeTracker.Entries<Person>().Single(); 

    if (userChanges.State == EntityState.Deleted) 
     throw new InvalidOperationException("wtf?"); 

    if (personChanges.State == EntityState.Deleted) 
     throw new InvalidOperationException("wtf?"); 

    return base.SaveChanges(); 
} 

जब यह कोड निष्पादित करता है, न तो InvalidOperationException फेंक दिया है।दोबारा, userChangesAdded राज्य में है, और personChangesUnchanged स्थिति में है।

मैं क्या गलत कर रहा हूं?

उत्तर

6

मुझे अभी वास्तव में गूंगा लगता है। इस सावधान प्रश्न को लिखने के बाद, अब यह स्पष्ट है।

Person मैं के साथ परीक्षण कर रहा हूँ पहले से मौजूद है, और पहले से ही एक अलग User.Name के साथ एक User सहयोग दिया है। यही कारण है कि user शून्य हो रहा है। Person.User संपत्ति को नए User पर सेट करने से पुराने User को Deleted स्थिति में रखा जा रहा है। रवींद्र।

अपना समय बर्बाद करने के लिए खेद है। मैं सवाल तब तक छोड़ दूंगा जब तक यह सहमति न हो कि इसे हटाना बेहतर होगा।

+0

तो आप इसे कैसे प्राप्त करते हैं? मुझे एक ऐसे विषय के साथ एक ही समस्या है जिसमें अंतिम पोस्ट एसोसिएशन है। यदि एक अंतिम पोस्ट पर अंतिम पोस्ट सेट करें, तो यह पिछले एक को हटाने की कोशिश करता है !! डब्ल्यूटीएफ क्या है? – leen3o

+2

यह * ओआरएम से ईएफ से एनएचबीरनेट को स्विच करने के लिए * समय * है! जे/के ... मेरे मामले में यह बहुतायत की बाधाओं के कारण था। प्रत्येक उपयोगकर्ता ** ** एक व्यक्ति होना चाहिए, लेकिन एक व्यक्ति के पास एक शून्य उपयोगकर्ता हो सकता है। जब मैं व्यक्ति को सेट करता हूं। उपयोगकर्ता को शून्य करने के लिए, ईएफ पहले यह देखने के लिए बाधाओं की जांच करता है कि रिश्ते के दूसरे पक्ष (User.Person) को शून्य पर सेट किया जा सकता है या नहीं। चूंकि यह नहीं हो सकता है, ईएफ उपयोगकर्ता को हटाए गए राज्य में डालता है। अगर मैंने उपयोगकर्ता को सेट किया था। पर्सन को शून्य करने के लिए, व्यक्ति ** ** को हटाए गए राज्य में नहीं रखा जाएगा, क्योंकि इसमें 0..1 उपयोगकर्ता हो सकता है। यदि आपकी बाधाएं अलग हैं, तो एक प्रश्न पोस्ट करें और मैं एक नज़र डालेगा। – danludwig

0

सुनिश्चित करें कि आप रिश्ते अपने मानचित्रण में परिभाषित (इकाई प्रकार विन्यास) किया हुआ है

उदाहरण के लिए:

this.HasRequired (टी => t.QuoteResponse) .WithMany (टी => t.QuoteResponseItems) .HasForeignKey (डी => डी .QuoteResponseID);

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