nhibernate: لا يمكن ضبط التحميل كسول بنجاح
-
20-08-2019 - |
سؤال
لديّ أحد الوالدين وطفل طاولة. يحتوي الطفل على مفتاح أجنبي على طاولة الوالدين ، مما يخلق علاقة واحدة. إليكم جزء من رسم الخرائط الذي أعرّفه مع 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>
.