سؤال

لدي نموذج أعلى نموذج قاعدة البيانات الخاص بي ورسم خريطة الكائنات في مستودعتي.

ومع ذلك ، من الواضح أنه يحدث فرقًا فيما إذا كنت "حدد" جديدًا "مباشرة في GetUsers أو" Select FactoryResult "كما هو موضح أدناه. أحصل على الخطأ في وقت التشغيل ، أن الطريقة CreateFromDBModel لا تحتوي على ترجمة إلى SQL (System.NotSupportedException).

هل هناك طريقة للتغلب على ذلك؟ هل يمكنني إصلاحه بطريقة ما؟

سبب الرغبة في استخدام طريقة المصنع هو أنني قد أقوم بتأسيس كائنات في مكان آخر وأريد الاحتفاظ برمز التعيين في مكان واحد ...

شكرا على أي تعليقات ، أندرس

    public IQueryable<User> GetUsers(bool includeTeams)
    {
        return from u in _db.sc_Players
               where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))
               select UserFactory2.CreateFromDbModel(u);
    }


    public static User CreateFromDbModel(sc_Player player)
    {
        return new User
                   {
                       Id = player.sc_PlayerID,
                       FirstName = player.FirstName.Trim(),
                       LastName = player.LastName.Trim(),
                       PresentationName = player.FirstName.Trim() + " " + player.LastName.Trim(),
                       LoginName = player.aspnet_User.LoweredUserName,
                       IsTeam = player.IsTeam,
                       Email = player.aspnet_User.aspnet_Membership.Email,
                       Password = player.aspnet_User.aspnet_Membership.Password
                   };
    }
هل كانت مفيدة؟

المحلول

هل المشكلة لأنك تعيد iqueryable في طريقة getUsers الخاصة بك؟ حاول إرجاع القائمة بدلاً من ذلك. هذا سيجبر استعلام LINQ على التنفيذ داخل الطريقة.

public List<User> GetUsers(bool includeTeams)
{
    return (from u in _db.sc_Players
    where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))
    select UserFactory2.CreateFromDbModel(u)).ToList();
}

لست متأكدًا مما إذا كان هذا سيصلح المشكلة ، بل مجرد حدس. تمكنت من تكرار ما تفعله في LINQPAD على قاعدة بيانات محلية ، وقد نجحت. لكن عينة لم تكن تعود إلى iqueryable. هل تقوم بتعديل مجموعة iQueryable خارج GetUsers ()؟

تعديل:

لقد فعلت بعض الفحص. تمكنت من تكرار الخطأ فقط عندما قمت بتعديل العينة الخاصة بي حتى تم استخدام مجموعة iQueryable في استعلام LINQ الثاني بعد استدعاء getusers ():

IQueryable<User> query = GetUsers(true);

var q = from u in query
    where u.Name.Contains("Bob")
    select new {Name = u.FirstName + " " + u.LastName};

أراهن إذا كنت ستعود إلى قائمة كما هو موضح أعلاه في GetUsers () سوف يختفي الخطأ. الجانب السلبي الوحيد هو أن أي تصفية تقوم بها بعد استدعاء GetUsers () لن يحد من مقدار البيانات التي يتم إرجاعها من قاعدة البيانات لأنك قد قمت بالفعل بتنفيذ الاستعلام عند الاتصال .Tolist ().

تحرير 2:

لسوء الحظ ، لا أعتقد أن هناك أي طريقة أخرى لتضمين طريقة المصنع في الاستعلام. لدي فكرة أخرى. يمكنك إنشاء طريقة تمديد لـ iQueryable ، تسميها شيئًا مثل TouserList (). داخل TouserList () يمكنك الاتصال بـ Tolist () على الاستعلام وطريقة المصنع التي تُرجع مجموعة من المستخدمين. اتصل بهذه الطريقة عند الانتهاء من تصفية البيانات باستخدام LINQ. سيسمح لك ذلك بتنفيذ الاستعلام فقط عندما تكون مستعدًا لتحميل البيانات من قاعدة البيانات. وفيما يلي مثال على ذلك.

public static List<Users> ToUserList(this IQueryable<User> query)
{
     return query.ToList().Select(u => UserFactory2.CreateFromDbModel(u)); 
}

استدعاء طريقة التمديد مثل هذا:

// Filter the data using linq. When you are ready to execute the query call:
query.ToUserList(); // Query will execute and a list of User objects returned.

أتمنى أن يكون هذا منطقيًا. دوغلاس H.

نصائح أخرى

الخطأ إلى حد كبير يفسر كل شيء.

"طريقة createfromdbmodel لا تحتوي على ترجمة إلى SQL (System.NotSupportedException)"

طريقة CreateFromDBModel ليست وظيفة SQL. لن يتمكن التطبيق الخاص بك من تشغيل وظيفة CreateFromDBModel حتى يتم إرجاع الكائنات إليك على وجه التحديد من الخادم. من المرجح أن تضطر إلى استدعاء tolist () أو شيء مشابه في استعلامك قبل أن تتمكن من تشغيل CreateFromDBModel عليها.

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