سؤال

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

public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        WithTable("Parents");

        Id(x => x.Id, "ParentID")
        .WithUnsavedValue(0)
        .GeneratedBy.Identity();

        Map(x => x.Description, "Description");

        HasMany<Child>(x => x.Childs)
        .LazyLoad()
        .WithKeyColumn("ParentID")
        .IsInverse()
        .AsSet();
    }
}

public class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        WithTable("Childs");

        Id(x => x.Id, "ChildID")
        .WithUnsavedValue(0)
        .GeneratedBy.Identity();

        References(x => x.Parent, "ParentID")
            .CanNotBeNull()
            .LazyLoad();
    }
}

كما ترون لقد قمت بتعيين Lazyload على العلاقة. لاحظ أيضًا أنه في فئات النماذج الخاصة بي ، يتم تعيين جميع الخصائص على أنها افتراضية.

الآن للاستعلام البسيط:

ICriteria crit = Session.CreateCriteria(typeof(Child))
    .Add(Expression.Eq("Id", 18));
IList<Child> list = crit.List<Child>();

و SQL المولدة:

SELECT this_.ChildID            as ChildID5_1_,
       this_.ParentID           as ParentID5_1_,
       parent2_.ParentID    as ParentID4_0_,
       parent2_.Description as Descript2_4_0_
FROM   Childs this_
       inner join Parents parent2_
         on this_.ParentID = parent2_.ParentID
WHERE  this_.ChildID = 18 /* @p0 */

كما ترون ، فإنه يقوم بالانضمام إلى الجدول الأصل ويحدد حقوله (المعرف والوصف). ولكن لماذا يفعل ذلك منذ أن طلبت lazyloading؟

الآن إذا قمت بتغيير الاستعلام إلى:

ICriteria crit2 = Session.CreateCriteria(typeof(Child))
    .SetFetchMode("Parent", FetchMode.Lazy)
    .Add(Expression.Eq("Id", 18));

هناك 2 استعلامات SQL تم إنشاؤها:

SELECT this_.ChildID  as ChildID5_0_,
       this_.ParentID as ParentID5_0_
FROM   Childs this_
WHERE  this_.ChildID = 18 /* @p0 */

وهو أمر جيد بالنسبة لي: لا انضمام ، لا يتم الاستعلام عن الجدول الأصل. لكني أحصل على هذه الثانية أيضًا:

SELECT parent0_.ParentID    as ParentID4_0_,
       parent0_.Description as Descript2_4_0_
FROM   Parents parent0_
WHERE  parent0_.ParentID = 45 /* @p0 */

الذي يستفسر مرة أخرى الجدول الأصل.

يتم إنشاء هاتين الاستعلامات 2 أثناء الخط:

IList<Child> list = crit.List<Child>();

أنا جاهل تمامًا بما يحدث هنا. هل يمكن لأحد أن يساعد؟

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

المحلول

سوف يعتمد على نسختك من nhibernate بطلاقة. حتى نقطة معينة كان الافتراضي أن جميع الكيانات سوف ليس تكون كسول محملة. هذا هو ما يعادل الإعداد الصريح lazy="false" في كيانك. لم يعد هذا هو الحال ، ولكن إذا كنت تعمل على أي شيء قبل هذه النقطة ، فسترى هذا السلوك.

يتم تجاوز إعداد التحميل البطيء من العديد إلى واحد/المراجع بواسطة الحمل الكسول على مستوى الكيان من الهدف ، لذلك إذا كنت تعمل على هذا الإصدار الأقدم من FNH ، فسيقوم إعداد الكيان بإعدادك References(...).LazyLoad() استدعاء Moot.

تحتاج إلى التحقق من أنك في أحدث إصدار من FNH ، يجب أن يصلح الأشياء ؛ ومع ذلك ، إذا لم يكن ذلك ، فأنت بحاجة إلى ضبط التحميل كسول بشكل صريح في Parent كيان. يمكنك القيام بذلك مع LazyLoad طريقة على ClassMap<T>.

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