سؤال

لدي تسلسل هرمي EF يبدو (مبسطًا بشكل كبير) كما يلي:

class Room { EntityCollection<Session> Sessions; }
class Session { EntityCollection<Whiteboard> Whiteboards; EntityReference Room; }
class Whiteboard { EntityCollection<WhiteboardShape> WhiteboardShapes; EntityReference Session; }
abstract class WhiteboardShape { EntityReference Whiteboard; }
class WhiteboardShapeEllipse : WhiteboardShape { }
class WhiteboardShapePolyline { WhiteboardShape { EntityCollection<PolylinePoint> PolylinePoints }
class PolylinePoint { EntityReference<WhiteboardShapePolyline> WhiteboardShapePolylineReference; }

بمعنى آخر، يمكن أن تحتوي الغرفة على جلسات متعددة؛يمكن أن تحتوي كل جلسة على ألواح معلومات متعددة؛ويمكن أن تحتوي كل لوحة معلومات على أشكال سبورة معلومات متعددة.يمكن أن تكون هذه الأشكال من أنواع مختلفة، بما في ذلك WhiteboardShapePolyline، والذي يمكن أن يحتوي في حد ذاته على نقاط متعددة متعددة الخطوط.

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

الآن، بالطبع، يتيح لك EF القيام بالتحميل المتحمّس، كما يلي:

      Room room = ctx.Room
            .Include("Sessions.Whiteboards")
            .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName);

لكن Include() لا يسمح لي بتحميل PolylinePoints.على وجه التحديد، إذا حاولت:

        Room room = ctx.Room
            .Include("Sessions.Whiteboards.WhiteboardShape.PolylinePoint")
            .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName);

أحصل على الاستثناء "مسار التضمين المحدد غير صالح.لا يعلن EntityType 'SlideLinc.Model.WhiteboardShape' عن خاصية التنقل بالاسم 'PolylinePoint'."

ولا هذا يعمل:

.Include("Sessions.Whiteboards.WhiteboardShapePolyline.PolylinePoint")

ولا هذا:

.Include("Sessions.Whiteboards.WhiteboardShape.WhiteboardShapePolyline.PolylinePoint")

ولا أي طريقة أخرى لتأطير مسار التنقل الذي يمكنني التفكير فيه.

الطريقة التي انتهيت بها من القيام بذلك بالتأكيد يبدو مثل الإختراق بالنسبة لي:

        // Make sure we've got everything loaded.
        if (room != null)
        {
            if (!room.Sessions.IsLoaded) { room.Sessions.Load(); }
            foreach (Session session in room.Sessions)
            {
                if (!session.Whiteboards.IsLoaded) { session.Whiteboards.Load(); }
                foreach (Whiteboard whiteboard in session.Whiteboards)
                {
                    if (!whiteboard.WhiteboardShape.IsLoaded) { whiteboard.WhiteboardShape.Load(); }
                    foreach (WhiteboardShape shape in whiteboard.WhiteboardShape)
                    {
                        if (shape is WhiteboardShapePolyline)
                        {
                            WhiteboardShapePolyline polyline = (WhiteboardShapePolyline)shape;
                            if (!polyline.PolylinePoints.IsLoaded) { polyline.PolylinePoints.Load(); }
                        }
                    }
                }
            }
        }

لقد نجح الأمر، لكنه يحتوي على تعليمات برمجية أكثر بكثير مما أريد، وهو عبارة عن مجموعة كاملة من الوصول إلى قاعدة البيانات أكثر مما أريد.

أقرب إجابة وجدتها هي هنا, ، لكن عقلي المسكين المتعطش لـ Linq لا يمكنه معرفة كيفية ترجمة رمز المثال إلى التسلسل الهرمي الأكثر تعقيدًا الذي أملكه؛بالإضافة إلى ذلك، فإن نموذج التعليمات البرمجية الموجود على هذا الرابط قبيح للغاية ويصعب فهمه.لا أريد حقًا أن يعتمد التسلسل الهرمي للكائن بالكامل على تأثير جانبي غامض وغير مرئي لكيفية بناء EF داخليًا لتسلسلاته الهرمية.

أي اقتراحات أخرى؟

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

المحلول

ربما سأستخدم الإسقاط لهذا الغرض.بدلاً من إرجاع أنواع الكيانات، قم بالمشروع على كائنات نقل البيانات خفيفة الوزن أو الأنواع المجهولة.عندما تقوم بالمشروع (على سبيل المثال، باستخدام استعلام LINQ)، يحدث التحميل تلقائيًا.لا تحتاج إلى تحديد تضمين في هذه الحالة.

نصائح أخرى

لقد كنت أواجه مشكلة مشابهة لمشكلة مشكلتك (مسار التنقل الأسهل) وأدركت أن PropertyName الموجود في ملف Designer.cs لم يكن كما توقعته.بمجرد أن قمت بتغييره إلى PropertyName في ملف المصمم، كان كل شيء يعمل بشكل جيد - لاحظ أيضًا أنني قمت بمسارين مختلفين وأصبحا:

.Include("UnexpectedNameA").Include("UnexpectedNameB")
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top