LINQ إلى الكيانات: لماذا لا يمكنني استخدام طريقة الانقسام كشرط؟

StackOverflow https://stackoverflow.com/questions/1354723

سؤال

لدي استعلام LINQ التالي:

var aKeyword = "ACT";
var results = from a in db.Activities
              where a.Keywords.Split(',').Contains(aKeyword) == true
              select a;

الكلمات الرئيسية هي حقل محدد فاصلة.

في كل مرة أقوم فيها بتشغيل هذا الاستعلام ، أحصل على الخطأ التالي:

"لا يتعرف LINQ على الكيانات على الطريقة التي تحتوي عليها" السلسلة] (System.Collections.generic.ienumerable`1 [system.string] ، system.string) ، ولا يمكن ترجمة هذه الطريقة إلى تعبير مخزن. "

ما هو البديل لما أحاول فعله؟

هل كانت مفيدة؟

المحلول

استجابة لاعتبارات أدائك على مجموعة بيانات كبيرة:

ستقوم بعمل سلسلة أحرف برية غير مفهرسة مطابقة للعميل ، لذلك نعم ، سيكون هناك خسارة في الأداء.

هل هناك سبب وراء وجود كلمات رئيسية متعددة في حقل جدول واحد؟ يمكنك تطبيع ذلك ، للحصول على جدول ActivityKeywords حيث يكون لديك عدد من سجلات الكلمات الرئيسية.

الأنشطة (Activity_id ، ... / * قم بإزالة حقل الكلمات الرئيسية * /) ---> ActivityKeywords (Activity_id ، keyword_id) ---> الكلمات الرئيسية (الكلمة الرئيسية ، القيمة)

تحقق من النموذج الطبيعي غير الأول: http://en.wikipedia.org/wiki/Database_Normalization

تحرير: أيضًا حتى لو كنت ستتمسك بالعمود الواحد ، فهناك طريقة للقيام بكل شيء خوادم (إذا كان لديك بناء جملة صارم: "الكلمة الرئيسية 1 ، الكلمة الرئيسية 2 ، ... ، الكلمة الرئيسية"):

var aKeyword = "ACT";
var results = (from a in db.Activities
              where a.Keywords.Contains("," + aKeyword) || a.Keywords.Contains(aKeyword + ",")
              select a;

نصائح أخرى

مشكلتك هي أن على LINQ-to-Eentites ترجمة كل ما تقدمه إلى SQL لإرساله إلى قاعدة البيانات.

إذا كان هذا هو ما عليك فعله حقًا ، فسيتعين عليك إجبار LINQ-to-ENTITITIONS على سحب جميع البيانات والكائنات من LINQ إلى OBCELT لتقييم الحالة.

السابق:

var aKeyword = "ACT";
var results = from a in db.Activities.ToList()
              where a.Keywords.Split(',').Contains(aKeyword) == true
              select a;

كن على دراية بأن هذا سيسحب جميع الكائنات من جدول الأنشطة. قد يكون البديل هو السماح لـ DB بعمل بعض المرشح الأولي ، وتصفية بقية الطريق بعد ذلك:

var aKeyword = "ACT";
var results = (from a in db.Activities
              where a.Keywords.Contains(aKeyword)
              select a).ToList().Where(a => a.KeyWords.Split(',').Contains(aKeyword));

سيتيح ذلك linq-to-Enterities القيام بالمرشح الذي يفهمه (السلسلة. تصبح contains استعلامًا مشابهًا) من شأنه تصفية بعض البيانات ، ثم قم بتطبيق المرشح الحقيقي الذي تريده عبر linq-to-objects بمجرد استرداد الكائنات . يجبر المكالمة TOLIST () على تشغيل LINQ-to-Enterities لتشغيل الاستعلام وإنشاء الكائنات ، مما يتيح أن يكون المحرك من LINQ-to-Objects هو المحرك الذي يقوم بالجزء الثاني من الاستعلام.

تخميني هو الطريقة التي تتصل بها الانقسام. يجب أن تأخذ صفيف. ربما يكون هناك انقسام آخر في LINQ يجد ويمنحك خطأ غير عادي:

هذا يعمل مع LINQ للكائنات:

 var dataStore = new List<string>
                    {
                        "foo,bar,zoo",
                        "yelp,foo",
                        "fred",
                        ""
                    };
 var results = from a in dataStore
               where a.Split(new[] {','}).Contains("foo")
               select a;

 foreach (var result in results)
 {
     Console.WriteLine("Match: {0}", result);
 }

يخرج ما يلي:

Match: foo,bar,zoo
Match: yelp,foo

في الواقع ، التفكير في الأمر ، هل تحتاج إلى الانقسام على الإطلاق؟ a.Contains("foo") قد يكون كافيا بالنسبة لك (إلا إذا كنت لا تريد أن تضرب foobar).

قد ترغب في انظر إلى هذا السؤال حول l2e و. contains للحصول على حل يجب أن يكون أكثر كفاءة من التخمين في Superset قبل تصفية جانب العميل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top