在ORM技术中无法正确理解延迟加载

时间:2014-11-18 16:09:24

标签: nhibernate lazy-loading

我是NHibernate的新手。我在sql server中创建了两个表,如UserDetails及其相应的Products表。映射就像! 我的实体类

公共类UserDetails     {

    [Required(ErrorMessage = "Please enter User Id")]
    public virtual string UserId { get; set; }
    [Required(ErrorMessage = "Please enter User Name")]
    public virtual string UserName { get; set; }
    [Required(ErrorMessage = "Please enter Password")]
    public virtual string Password { get; set; }
    [Required(ErrorMessage = "Please enter Email Id")]
    [EmailAddress(ErrorMessage = "Please enter proper Email Id")]
    public virtual string EmailId { get; set; }
    [Required(ErrorMessage = "Please enter Address")]
    [DataType(DataType.MultilineText)]
    public virtual string Address { get; set; }
    [Required(ErrorMessage = "Please enter Phone No")]
    public virtual string PhoneNo { get; set; }

    public virtual ISet<Product> Products { get; set; }
}

公共类产品     {

    [HiddenInput(DisplayValue=false)]
    public virtual int ProductID { get; set; }
    [Required(ErrorMessage="Please enter a product name")]
    public virtual string Name { get; set; }
    [DataType(DataType.MultilineText)]
    [Required(ErrorMessage = "Please enter a description")]
    public virtual string Description { get; set; }
    [Required]
    [Range(0.01,double.MaxValue,ErrorMessage="Please enter a positive price")]
    public virtual decimal Price { get; set; }
    [Required(ErrorMessage = "Please specify a category")]
    public virtual string Category { get; set; }
    public virtual byte[] ImageData { get; set; }
    [HiddenInput(DisplayValue=false)]
    public virtual string ImageMimeType { get; set; }
    public virtual UserDetails UserDetail { get; set; }
}

映射 UserDetails.hbm.xml

<class name="SportsStore.Domain.Entities.UserDetails,SportsStore.Domain" table="UserDetails" lazy="true" >
<id name="UserId" column="UserId" access="property" type="String" >
  <generator class="assigned"></generator>
</id>
<property name="UserName" column="UserName" access="property" type="String" ></property>
<property name="Password" column="Password" access="property" type="String"></property>
<property name="EmailId" column="EmailId" access="property" type="String" ></property>
<property name="Address" column="Address" access="property" type="String" ></property>
<property name="PhoneNo" column="PhoneNo" access="property" type="String"  ></property>
<set name="Products" lazy="true" cascade="all-delete-orphan" inverse="true" >
  <key column="UserId" ></key>
  <one-to-many class="SportsStore.Domain.Entities.Product"></one-to-many>
</set>

Products.hbm.xml

  <class name="SportsStore.Domain.Entities.Product,SportsStore.Domain" table="Products">
<id name="ProductID" column="ProductID" access="property" type="Int32" >
  <generator class="native"></generator>
</id>
<property name="Name" column="Name" access="property" type="String">
</property>
<property name="Description" column="Description" access="property" type="String"></property>
<property name="Price" column="Price" access="property" type="decimal"></property>
<property name="Category" column="Category" access="property" type="String"></property>
<property name="ImageData" column="ImageData" access="property" type="BinaryBlob" length="2147483647"></property>
<property name ="ImageMimeType" column="ImageMimeType" access="property" type="String" ></property>
<many-to-one name="UserDetail" column="UserId" class="SportsStore.Domain.Entities.UserDetails" access="property" cascade="all"></many-to-one>

var user = (from userDetails in _session.Query<UserDetails>()
                    where userDetails.UserId == userId && userDetails.Password == password
                    select userDetails);

我以为我将仅从用户详细信息中获取数据,因为延迟加载应用于它,但在调试模式下,我也可以看到来自products表的数据。为什么?我是以错误的方式理解延迟加载还是我的映射中有任何错误?根据我的知识,延迟加载仅按需加载数据意味着如果我们迭代然后数据从products表加载。

1 个答案:

答案 0 :(得分:1)

你的假设:

  

...根据我的知识,延迟加载仅按需加载数据意味着如果我们迭代然后数据从产品表加载

绝对正确。没有但是。仅在需要时,例如,如果我们想要迭代它们。而这恰好发生在调试窗口中。

调试窗口是应用程序,因为其他一些winform,exe,wpf ...它只是提供原生/内置的UI来观察我们的objcets。一旦我们开始观察/迭代它们 - 他们意识到有需求 - 来自产品表的数据被加载。

如何确定?

没那么复杂。在开始观察“调试”窗口中的任何对象之前,请调用: session.Clear() 。从那时起,只有已装载的东西将在稍后提供。

  

因此,在调试窗口中,我们现在应该看到一些关于延迟加载失败的例外 ......