Fluent NHibernate do not load linked collection - fluent-nhibernate

I've got two simple entities:
public class Post {
public virtual int Id {get;set;}
public virtual string Title {get;set;}
public virtual IList<Comment> {get;set;}
}
and
public class Comment {
public virtual int Id {get;set;}
public virtual string Text {get;set;}
public virtual Post Post {get;set;}
}
Corresponding mappings looks like:
HasMany(x => x.Comment).LazyLoad();
References(x => x.Post).Not.LazyLoad();
My goal is to load Comments in Posts only if I want it and don't load Comments otherwise. something like that:
var posts = session.QueryOver<Post>().ToList() // load posts without comments
var posts = session.QueryOver<Post>().FetchMany(x => x.Comments).ToList(); // load posts with comments
I'm using FluentNHibernate 2.0.1 and NHibernate 4 with Postgres 9.2

the lazy load convention works mostly on list's only, I have tried my fair share of troubles when I tried to use it on non-collection child elements.
So yes, you can use .Conventions.Add(DefaultLazy.Always()) but that should be preferred for collections only

Related

Problem Understanding Fluent nHibernate Automapping and Relationship

I am a bit new to Fluent nHibernate and ran into a scenario with my schema I'm not sure how to address.
Say I have two tables:
Track
TrackId
UserId
Name
Users
UserId
Name
Now, what I want to do is have the ability to access the related User object by track. For example:
var track = repo.GetById(1);
var userName = track.User.Name;
How can I get nHibernate to automap this new custom User property?
Here you go:
public class Track
{
public virtual int Id {get;set;}
public virtual string Name {get;set;}
public virtual User User {get;set;}
}
public class User
{
public virtual int Id {get;set;}
public virtual string Name {get;set;}
}
// Usage
var track = repo.GetById(1);
var username = track.User.Name;
More information can be found here.

Selecting objects not in a collection in NHibernate with ICriteria Interface

In my system Users own 0 or more Categories. Here is a simplified version of my model classes:
public class User
{
public virtual String Name {get; set;}
public virtual IList<Category> Categories { get; set; }
}
public class Category
{
public virtual String Title {get; set;}
}
I now want to create an ICriteria query to select all categories that aren't assigned to a user, but I'm stuck. Ideally I don't want to create a navigation property from Category to User, but with my beginner knowledge of NHibernate that's the only solution I can see.
Is there an ICriteria query that will do this with the current data model classes?
Thanks for your help.
This is off the top of my head, but might be a useful pointer.
var crit = _session.CreateCriteria<Category>("c")
.Add(
Subqueries.PropertyNotIn("c.id",
DetachedCriteria.For<User>("u")
.CreateCriteria("Categories","uc")
.SetProjection(Projections.Property("uc.id"))
));
var unassignedCategories = crit.List<Category>();
You can probably get a feel for the SQL that will be generated here:
select c.* from categories where c.id not in (select uc.id from usercategories)
Hope this helps, and sorry I haven't been able to test it :)
Tobin

nHibernate Criteria query with missing mapping

I'm trying to do the following thing:
ICriteria criteriaSelect =
session
.CreateCriteria(typeof(Employees))
.CreateCriteria("Orders")
;
var test = criteriaSelect.List<Orders>();
With:
public class Orders{
public virtual int OrderID { get; private set;}
}
public class Employees{
public virtual int EmployeeID { get; private set;}
public virtual IList<Orders> Orders { get; private set; }
}
And I get the error: "No persister for: Employees".
Please note that for decoupling reason, I don't want Orders to
reference Employees.
Thanks for your help,
Stephane
The Criteria API is for indicating the specification you want during the query. You will need to establish mappings for your entities using either the older hbm.xml files or using Fluent NHibernate. See chapter 5 on Basic O/R Mapping for more details.

FluentNHibernate mapping for Dictionary

What is the best way of mapping a simple Dictionary property using Fluent NHibernate?
public class PersistedData
{
public virtual IDictionary<key, value> Dictionary { get; set; }
}
public class PersistedDataMap : ClassMap<PersistedData>
{
HasMany(x => x.Dictionary)
.Table("dict_table")
.KeyColumn("column_id")
.AsMap<string>("key")
.Element("value");
}
This will properly map Dictionary to table dict_table and use column_id to associate it to the base id.
As a side note, if you would like to use an Enum as the Key in the dictionary, it should be noted that NHibernate.Type.EnumStringType<MyEnum> can be used in place of the string in .AsMap<string> to use the string value instead of the Ordinal.
Using a simple class relationship such as the following:
public class Foo {
public virtual IDictionary<string, Bar> Bars { get; set; }
}
public class Bar {
public virtual string Type { get; set; }
public virtual int Value { get; set; }
}
You can map this with Fluent NHibernate in this way:
mapping.HasMany(x => x.Bars)
.AsMap(x => x.Type);
Where Bar.Type is used as the key field into the dictionary.
To map a list as a dictionary:
HasMany(x => x.Customers)
.AsMap();
I have not used it; so cannot give an example.
Have look at the wiki: Cached version of the page, Actual page I have given the cached version of the page as the site seems to be down.

Mapping a derived class with additional collection property in nhibernate

I'm trying to use the table-per-subclass (which fluent-nhibernate automaps by default) with a class structure like the following:
public class Product
{
public virtual int Id{ get; set; }
public virtual string Title{ get; set; }
}
public class ProductPackage : Product
{
public ProductPackage(){ Includes = new List<Product>(); }
public virtual IList<Prodcut> Includes{ get; private set; }
[EditorBrowsable( EditorBrowsableState.Never )]
public class ProductPackageAutoOverride : IAutoMappingOverride<ProductPackage>
{
public void Override( AutoMap<ProductPackage> mapping )
{
mapping.HasManyToMany( x => x.Includes )
.WithTableName( "IncludesXProduct" )
.WithParentKeyColumn( "ProductId" )
.WithChildKeyColumn( "IncludesProductId" )
.Cascade.SaveUpdate();
}
}
}
Instead of adding a new table "IncludesXProduct" to represent the many-to-many mapping, it adds a property "ProductPackageId" to the Product table. Of course persisting to this schema doesn't work.
Have I missed something simple or is this type of thing not really supported by NHibernate?
It is possible to do this with NHibernate. Unfortunately my fluent syntax isn't very good, but it looks like FNH is somehow regarding the relationship as a many-to-one rather than a many-to-many.
If you tag your question with "fluent-nhibernate" then you may get more knowledgeable people answering.