2015-12-20 15 views
5

पर मैं इस परिदृश्य पर मिल गया है:EF6 अद्वितीय बाधा विदेशी कुंजी

public class Book { 
     [Key] 
     public string Isbn { get; set; } 
     public string Title { get; set; } 
     public int Stock { get; set; } 
     public Author Author { get; set; } 
} 

public class Author { 
    public int AuthorId { get; set; } 
    [Index(IsUnique = true)] 
    [StringLength(50)] 
    public string Name { get; set; } 

    public ICollection<Book> Books { get; set; } 
} 

मैं अगर जरूरत किताबें, और संबद्ध लेखकों सम्मिलित करने के लिए देख रहा हूँ। मैं निम्नलिखित अनुभवहीन कोड है, जो टूट जाता है (काफी उम्मीद है):

var author = _ctx.Authors.FirstOrDefault(x => x.Name == command.Author); 

if (author == null) 
    author = new Author { Name = command.Author }; 

var book = new Book 
{ 
    Isbn = command.Id, 
    Title = command.Title, 
    Stock = command.Count, 
    Author = author 
}; 

_ctx.Books.Add(book); 

await _ctx.SaveChangesAsync(); 

क्या मैं दिखाई दे रही है है कि कभी कभी, FirstOrDefault अशक्त लौट रहा है, लेकिन डालने पर अद्वितीय सूचकांक के उल्लंघन के कारण विफल हो रहा है लेखक का नाम क्या कुछ ईएफ चाल है जो इसे सरल तरीके से होने की अनुमति देगी? मुझे लगता है कि मैं एक संग्रहित प्रो का उपयोग कर सकता हूं, लेकिन यदि संभव हो तो इसे क्लाइंट साइड करना चाहूंगा।

+1

एकमात्र कारण मैं देख सकता हूं कि यह तोड़ देगा यदि आप एक साथ कई पुस्तकों को जोड़ रहे हैं और 'लेखक' जोड़ा गया है जब आप इसे देखते हैं और जब आइटम संग्रह में जोड़ा जाता है तो एक और प्रक्रिया के द्वारा। इस तरह के समेकन मुद्दे को संभालने का सबसे आसान तरीका, मेरी राय में, अपवाद को पकड़ना होगा, पुस्तक को उस लेखक को संलग्न करें जो अब डीबी में है, और फिर पुनः सबमिट करें। – Claies

+0

1. क्या आपने कोशिश की? लेखक। पुस्तकें जोड़ें (पुस्तक); ctx.SaveChangesAsync(); 2. पुस्तक में जोड़ें: सार्वजनिक int लेखक आईडी {प्राप्त करें; सेट; } सार्वजनिक वर्चुअल लेखक लेखक {प्राप्त करें; सेट; } – W92

+0

क्लेज़ का अवलोकन सही है ... दौड़ बिल्कुल समस्या है, और मैं एक कामकाज खोजने की कोशिश कर रहा हूं। @ W92, हाँ ... कोशिश की। एक ही दौड़ की स्थिति उत्पन्न होती है। मुद्दा लेखक डालने पर है। – ashic

उत्तर

3

विभिन्न चीजों की कोशिश कर के बाद, मैं निम्नलिखित के साथ चले गए हैं:

var author = _ctx.Authors.SqlQuery(
    "with data as (select @author as [name]) " + 
    "merge Authors a " + 
    "using data s on s.[name] = a.[name] " + 
    "when not matched by target " + 
    "then insert([name]) values(s.[name]); select * from Authors where [name][email protected]", new SqlParameter("author", command.Author)).Single(); 


var book = new Book 
{ 
    Isbn = command.Id, 
    Title = command.Title, 
    Stock = command.Count, 
    Author = author 
}; 

_ctx.Books.Add(book); 

await _ctx.SaveChangesAsync(); 

जबकि सुंदर नहीं, तो इस लेखक की जांच और सम्मिलन db देशी सुविधाओं का उपयोग कर के बीच रेस स्थिति को रोकने के है। ओआरएम और लीकी अबास्ट्रक्शन, एएच :)

मुझे लगता है कि मैं वहां भी पुस्तक डालने डाल सकता हूं, या पूरी चीज को एक स्पोक बना सकता हूं। अगर कोई इस परिदृश्य को पूरा करने वाले ओआरएम मूल दृष्टिकोण के साथ आता है, तो मैं सभी कान हूं :)

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