2016-06-03 9 views
11

में मैपिंग अभिव्यक्तियां मेरे पास एक सारणी कक्षा है जिसे दो वर्गों द्वारा विरासत में मिला है। दोनों वर्ग डेटाबेस में टेबल का प्रतिनिधित्व करते हैं। मुझे अमूर्त वर्ग में अभिव्यक्तियों को मैपिंग में परेशानी हो रही है और इसलिए मुझे अपवाद मिलते हैं कि इसका अनुवाद एसक्यूएल में नहीं किया जा सकता है। स्टैकओवरफ्लो में मिले सभी प्रश्न कॉलम के बारे में बात कर रहे हैं जो पहले से ही मेरे लिए काम कर रहा है।LINQ-to-sql अमूर्त वर्ग

नीचे एक बहुत ही सरल कोड है जो दिखाता है कि मेरा क्या मतलब है। कार और मोटरसाइकिल में _isNew अभिव्यक्ति के पूरी तरह कार्यान्वयन है।

public abstract class Vehicle { 
    public abstract boolean IsNew; 
} 

public partial class Car: Vehicle { 
     public override boolean IsNew { 
     get { _isNew.Invoke(this); } 
     } 
} 
public partial class Motorcycle: Vehicle { 
     public override boolean IsNew { 
     get { _isNew.Invoke(this); } 
     } 
} 

मैं एक IQueryable पर या तो _isNew अभिव्यक्ति या IsNew संपत्ति कॉल करने के लिए सक्षम होने के लिए चाहते हैं और अभी तक इसे चलाता मामले वाहन में कार वर्ग की _isNew कार का प्रकार है। क्या वैसे भी मैं इसे पूरा कर सकता हूं? मेरे द्वारा किए गए सभी समाधानों ने अपवाद का कारण बना दिया कि इसका अनुवाद एसक्यूएल में नहीं किया जा सकता है।

+0

'_isNew' क्या है? एक अभिव्यक्ति नहीं हो सकती है जिसे * अनुवादित किया जा सकता है? –

+0

_isNew एक अभिव्यक्ति एसक्यूएल (करने के लिए अनुवाद किया जा सकता है कि जैसे कारों के लिए अभिव्यक्ति <समारोह <वाहन, bool >> _isNew = (v) => v.Age <2; मोटरसाइकिल के लिए अभिव्यक्ति <समारोह <वाहन, bool >> _isNew = (v) => v.Age <1; (पीएस: आयु एक डीबी कॉलम है) मेरा मुख्य मुद्दा यह है कि मैं वंचित वर्ग के आधार पर वाहन पर सही _isNew को कैसे लागू कर सकता हूं। कॉलिंग फ़ंक्शन IsNew SQL अनुवाद त्रुटि का कारण बनता है और मैं यह तय नहीं कर सकता कि किस प्रकार IINew को बिना किसी प्रकार की जांच किए और बिना किसी कास्टिंग किए। – Sami

+0

मुझे लगता है कि यह बिल्कुल काम नहीं करेगा क्योंकि IsNew के ओवरराइड को कॉल करने के लिए कार या मोटरसाइकिल का एक ठोस उदाहरण आवश्यक होगा। नतीजतन ईएफ को उन उदाहरणों को बनाने के लिए पहले आइटमों से पूछना होगा। – Peit

उत्तर

1

आपके प्रश्न में आने से पहले, आपको शायद best practices of C# properties concerning exceptions पर जांच करनी चाहिए।

आप अपनी सूची लोड करने के लिए उत्सुक हो सकते हैं, और फिर बाद में अपनी IsNew संपत्ति को कॉल कर सकते हैं, जो लिंक-टू-एसक्यूएल त्रुटि को खत्म कर देगा। लेकिन मैं समझता हूं कि यदि आप IsNew पर डेटा के बड़े सेट पर फ़िल्टर करने के लिए भरोसा कर रहे हैं तो प्रदर्शन समस्याओं का कारण बन सकता है।

मुझे लगता है कि आपकी समस्या वास्तव में आप "IsNew" संपत्ति प्राप्त करने के लिए उदाहरण का उपयोग करना चाहते हैं। लेकिन आप बस नहीं कर सकते हैं क्योंकि linq-to-sql उचित रूप से when you are trying to use a property that is not mapped to a column शिकायत करेगा।

तो यदि आप किसी उदाहरण का उपयोग नहीं कर सकते हैं, तो अगली सबसे अच्छी चीज़ क्या है?

खैर शायद मैं एक स्थिर अभिव्यक्ति

public partial class Motorcycle : Vehicle 
{ 
    public static Expression<Func<Vehicle, bool>> IsNew { get { return (v) => v.Age <= 1; } } 
} 

public partial class Car : Vehicle 
{ 
    public static Expression<Func<Vehicle, bool>> IsNew { get { return (v) => v.Age <= 2; } } 
} 

जो तुम जैसे

var newCars = db.Cars.Where(Car.IsNew).ToList(); 
var newMotorcycles = db.Motorcycles.Where(Motorcycle.IsNew).ToList(); 

उपयोग कर सकते हैं या आप तर्क खींच सकता है बाहर अपने आवेदन और में ऐसा तय होगी SQL सर्वर computed column के रूप में, जिसे मैं व्यक्तिगत रूप से सोचता हूं वह आपका सबसे अच्छा विकल्प है।

+0

उत्तर के लिए धन्यवाद। आपके प्रस्ताव के साथ मेरा मुख्य मुद्दा यह है कि मैं हमेशा इस प्रकार को नहीं जानता, इसलिए मैं IsNew अभिव्यक्ति को चलाने से पहले कई स्थानों और कास्टिंग में टाइपिंग को समाप्त कर दूंगा। मैं इस निष्कर्ष पर पहुंचा कि मैं इसे अकेले LINQ के साथ नहीं कर सकता लेकिन किसी भी तरह से गंदा कामकाज खोजने में कामयाब रहा: मैंने LINQKit ExpandableQuery का उपयोग किया और सही अभिव्यक्ति चुनने के लिए पूरे तर्क को बढ़ाया। इस तरह, कक्षा वाहन को LINQ को कभी नहीं भेजा जाता है और केवल कार और मोटरसाइकिल का इलाज किया जाता है। – Sami

+0

हालांकि एक बहुत ही साफ समाधान नहीं है, हालांकि मैं आपके साथ गणना की गई कॉलम, संग्रहीत प्रक्रियाओं, SQL सर्वर में सभी को संभालने के विचारों के बारे में दृढ़ता से सहमत हूं। लेकिन मैं LINQ में पहले से परिभाषित सभी अभिव्यक्तियों के साथ एक मौजूदा बड़ी परियोजना पर काम कर रहा हूं। उनको फिर से लिखने में महीनों लगेंगे और इसलिए LINQ विधि ढूंढना पसंद करेंगे। – Sami

+0

मैं मदद नहीं कर सकता लेकिन महसूस करता हूं कि किसी तरह से प्रतिबिंब आपको किसी तरह से मदद कर सकता था, यह सी # का एक बहुत भ्रमित पहलू है, यदि आपके पास पहले से इसका अनुभव नहीं है, तो यह उपयोग करने में समय प्रभावी नहीं हो सकता है। हालांकि मैंने व्यक्तिगत रूप से पाया है कि इस तरह की कठिन संरचनात्मक समस्याओं को अक्सर प्रतिबिंब के साथ हल किया जा सकता है। – Shadetheartist

0

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

var vehicule = new Car(); 
+0

प्रश्न डेटाबेस के मैपिंग और अभिभावक सार वर्ग के साथ दो वर्गों के linq-to-sql अनुवाद के बारे में है। यह सिर्फ एक सामान्य विरासत/अमूर्त वर्ग नहीं है। – Sami

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