Cannot understand lazy loading properly in ORM tec

2019-09-07 05:41发布

问题:

I am new to NHibernate. I have created two tables in sql server like UserDetails and its corresponding Products table. The mapping are like! My entity classes

public class 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; }
}

public class Product {

    [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; }
}

Mapping 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);

I thought I will get data from only userdetails as lazy loading is applied to it, but on debug mode I can see data from products table too. why? am I understood lazy loading in wrong way or is there any bug in my mapping? According to my knowledge lazy loading loads the data only on demand means if we iterate then the data gets loaded from products table.

回答1:

Your assumption:

...According to my knowledge lazy loading loads the data only on demand means if we iterate then the data gets loaded from products table

Is absolutely correct. There is no but. Only on demand, for example if we want to iterate them. And exactly that is happening in the debug window.

Debug window is application as some other winform, exe, wpf... It simply prvides native/built in UI to observe our objcets. And once we start to observe/iterate them - they realize that there is demand - data from products table is loaded.

How to be sure?

Not so complicated. Just before starting to observe any object in the Debug window, call: session.Clear(). From that moment, only stuff already loaded will be available later.

So, in debug window, we should now see some exception about lazy loading failure...