केवल इनिशियलाइज़र, इकाई सदस्य और निकाय नेविगेशन गुण समर्थित हैं


102

मुझे यह अपवाद मिल रहा है:

LINQ Entities में निर्दिष्ट प्रकार का सदस्य 'पेड' समर्थित नहीं है। केवल इनिशियलाइज़र, इकाई सदस्य और निकाय नेविगेशन गुण समर्थित हैं।

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .Where(o => o.Paid == false)
            .OrderByDescending(o => o.DateCreated);

        return View(debts);
    }

मेरा मॉडल वर्ग

public partial class Order
{
    public bool Paid {
        get {
            return TotalPaid >= Total;
        }
    }

    public decimal TotalPaid {
        get {
            return Payments.Sum(p => p.Amount);
        }
    }

भुगतान एक संबंधित तालिका है जिसमें फ़ील्ड राशि होती है, क्वेरी काम करती है यदि मैं भुगतानों के बारे में सही जानकारी दिखा रहा है, तो कोई भी सुराग कोड के साथ गलत क्या है?

इसके साथ सुझाए गए उत्तर की तरह हल:

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .OrderByDescending(o => o.DateCreated)
            .ToList()
            .Where(o => o.Paid == false);

        return View(debts);
    }

15
सरल उत्तर: आप linq-to-संस्थाओं के प्रश्नों में मैप किए गए गुणों का उपयोग नहीं कर सकते हैं! केवल मैप किए गए गुण SQL में अनुवादित हैं।
लादिस्लाव मृंका

जवाबों:


114

इकाई आपकी भुगतान की गई संपत्ति को SQL में बदलने की कोशिश कर रही है और ऐसा नहीं कर सकती क्योंकि यह टेबल स्कीमा का हिस्सा नहीं है।

आप जो कर सकते हैं वह है एंटिटी को टेबल को बिना किसी भुगतान फ़िल्टर के क्वेरी करने दें और फिर भुगतान किए गए लोगों को फ़िल्टर न करें।

public ActionResult Index()
{
    var debts = storeDB.Orders
        //.Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

    debts = debts.Where(o => o.Paid == false);

    return View(debts);
}

बेशक, इसका मतलब यह होगा कि आप सभी डेटा को वेब सर्वर पर वापस ला रहे हैं और उस पर डेटा को फ़िल्टर कर रहे हैं। यदि आप DB सर्वर पर फ़िल्टर करना चाहते हैं, तो आप टेबल पर एक परिकलित कॉलम बना सकते हैं या एक संग्रहीत प्रक्रिया का उपयोग कर सकते हैं।


25

बस एक समान समस्या को हल करना था। उपरोक्त समाधानों में इन-मेमोरी प्रोसेसिंग की आवश्यकता होती है, जो एक बुरा अभ्यास (आलसी लोडिंग) है।

मेरा समाधान एक सहायक लिखना था जिसने एक विधेय लौटाया:

public static class Extensions
{
    public static Expression<Func<Order, bool>> IsPaid()
    {
        return order => order.Payments.Sum(p => p.Amount) >= order.Total;
    }
}

आप अपने linq स्टेटमेंट को फिर से लिख सकते हैं:

var debts = storeDB.Orders
                    .Where(Extensions.IsPaid())
                    .OrderByDescending(o => o.DateCreated);

यह तब आसान है जब आप गणना तर्क (DRY) का पुन: उपयोग करना चाहते हैं। नकारात्मक पक्ष यह है कि तर्क आपके डोमेन मॉडल में नहीं है।


1
कई पुस्तकालय हैं जो इस दृष्टिकोण को और अधिक बनाने का प्रयास करते हैं "निर्मित: देखें": stackoverflow.com/a/27383641/470183 । लिनक-टू-इकाइयां "कैन्यनियल फंक्शंस" का उपयोग करते हुए अभिव्यक्तियों तक सीमित है - जिसे एसक्यूएल में बदल दिया जा सकता है। C # 6 ने "एक्सप्रेशन बॉडीड फ़ंक्शंस" की शुरुआत की, लेकिन ये सच नहीं हैं लैम्ब्डा (देखें: stackoverflow.com/a/28411444/470183 )। फिर भी फ्रेमवर्क में ऐसा होना अच्छा होगा इसलिए WIBNI data.uservoice.com/forums/…
जेम्स

1
इस सरल और संक्षिप्त उदाहरण के लिए धन्यवाद Expression<Func<xx,yy>>। मैंने पहले कभी इसे समझा था, लेकिन अब यह स्पष्ट दिखता है।
एलेक्सबी

17

यह समस्या ए से भी आ सकती है [NotMapped] प्रॉपर्टी है, जिसका नाम आपके DB मॉडल और व्यू मॉडल में समान है।

AutoMapper एक प्रक्षेपण के दौरान DB से इसे चुनने की कोशिश करता है; और NotMapped संपत्ति स्पष्ट रूप से DB में मौजूद नहीं है।

Ignoreडीबी मॉडल से व्यू मॉडल में मैपिंग करते समय इसका समाधान ऑटोमैपर कॉन्फिगरेशन में मौजूद प्रॉपर्टी के लिए होता है।

  1. एक के लिए देखो [NotMapped]नाम के साथ संपत्ति Fooअपने डीबी मॉडल में।
  2. Fooअपने व्यू मॉडल में समान नाम वाली प्रॉपर्टी देखें।
  3. यदि ऐसा है, तो अपने AutoMapper कॉन्फिगर को बदलें। जोड़ना.ForMember(a => a.Foo, b => b.Ignore());

डांग AutoMapper प्रोजेक्शन मुझे भी पकड़ा, उत्तर के लिए धन्यवाद!
चेस फ्लोरल

15

Linq बयान को SQL स्टेटमेंट में परिवर्तित करता है और उन्हें डेटाबेस में निष्पादित करता है।

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

इसलिए समग्रता में,

var debts = storeDB.Orders.toList()
        .Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

21
मैं सुझाव दूंगा कि किसी को आदेश देने के लिए पूछना () आदेशों पर खतरनाक है क्योंकि इसका मतलब पूरी सूची को पुनः प्राप्त करना होगा
elgrego

यह मेरे लिए अच्छा है क्योंकि मेरी समस्याग्रस्त संपत्ति समन लिनेक फंक्शन में है जहां क्लॉज नहीं है। इसलिए मुझे अनावश्यक डेटा नहीं मिल रहा है और जो डेटा रेट किया गया है उस पर मैं Linq Sum फंक्शन कर रहा हूं जो लिस्ट पर काम कर रहा है। धन्यवाद! पहली बार में जो बुरा लग सकता है वह कुछ स्थितियों में बहुत मददगार हो सकता है!
डोवर मिलर

11

अन्य संभावित कारण यह है कि आप IEnumerableअपनी संपत्ति के लिए उपयोग कर रहे हैं, इसके बजायICollection

इसलिए इसके बजाय:

public class This
{
    public long Id { get; set; }
    //...
    public virtual IEnumerable<That> Thats { get; set; }
}

यह करो:

public class This
{
    public long Id { get; set; }
    //...
    public virtual ICollection<That> Thats { get; set; }
}

और आप हंसी डोरी ... बेवकूफ़ चीज़ 2 घंटे से अधिक खोने के लिए।


2

यह स्थिति तब भी हो सकती है यदि आप EntityFramework प्रकारों , जैसे अहस्ताक्षरित int द्वारा उपयोग नहीं कर रहे हैं ।

यह मेरी ऐसी त्रुटि का मामला था।

समर्थित प्रकारों के बारे में और जानकारी देखें: https://msdn.microsoft.com/en-us/library/ee382832(v=vs.100).aspx

GFoley83 द्वारा बताई गई ऐसी स्थितियों के लिए कुछ समाधान है: एंटिटी फ्रेमवर्क के साथ अहस्ताक्षरित इंट / लंबे प्रकार का उपयोग कैसे करें?


इस लिंक ने काफी समय बचाया! आपका बहुत बहुत धन्यवाद!
व्लादिमीर सेमास्किन

0

मुझे इस समस्या का सामना करना पड़ा क्योंकि केवल get without setसंपत्ति के साथ एक सदस्य चर रहा था

इसका मतलब है कि इसके auto calculatedऔर not storedएक स्तंभ के रूप मेंthe table

इसलिए इसके not existमेंtable schema

इतना make sureहै कि किसी भी सदस्य चर not auto calculatedकरने के लिए haveएक getterऔर setterगुण


-1

आपके edmx और संदर्भ मॉडल में कुछ अलग-अलग संपत्ति है, जिसे db में नया जोड़ा गया है।

अपने EDMX को अपडेट करें इसे ठीक से ताज़ा करें अपनी परियोजना को फिर से शुरू करें और फिर से चलाएं।

यह आपकी समस्या को हल कर देगा।

सादर गणेश निकम

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.