Reputation: 461
In the CategoriesTranslated collection i have this error: illegal access to loading collection.
public class Category : Entity
{
public Category()
{
CategoriesTranslated = new List<CategoryTranslated>();
}
public virtual Category Parent { get; set; }
public virtual string Name { get; set; }
public virtual IList<CategoryTranslated> CategoriesTranslated { get; set; }
}
public class CategoryTranslated : Entity
{
public CategoryTranslated()
{
}
public virtual Category Category { get; set; }
public virtual LanguageType Language { get; set; }
public virtual string Name { get; set; }
}
public void Override(AutoMapping<Category> mapping)
{
mapping.HasMany(x => x.CategoriesTranslated)
.Inverse()
.Cascade.All();
}
public void Override(AutoMapping<CategoryTranslated> mapping)
{
mapping.References(x => x.Category);
}
The SQL:
CREATE TABLE Category(
[Id] smallint primary key identity(1,1),
[Parent] smallint null,
[Name] varchar(50) not null unique,
)
alter table [Category] add CONSTRAINT fk_Category_Category
FOREIGN KEY(Parent) references Category (Id)
go
CREATE TABLE CategoryTranslated(
[Id] smallint primary key identity(1,1),
[Category] smallint not null,
[Language] tinyint not null,
[Name] varchar(50) not null,
)
alter table [CategoryTranslated] add CONSTRAINT fk_CategoryTranslated_Category
FOREIGN KEY(Category) references Category (Id)
go
Where is it wrong?
UPDATE The links to the hbm generater:
Category:
http://uploading.com/files/fmb71565/SubmitSiteDirectory.Core.Category.hbm.xml/
Category translated: http://uploading.com/files/9c9aaem9/SubmitSiteDirectory.Core.CategoryTranslated.hbm.xml/
Upvotes: 2
Views: 3126
Reputation: 12833
I am guessing it has to do with the creation of the list inside the constructor, especially if you left a default ctor for NHib. And that NHib is trying to set the list before it's created. The other complication here is that you have a bi-directional relationship, and CategoryTranslated may be trying to get at the list before its created too.
I doubt this is the only solution, but here is a pattern I use that should solve the error:
/// <summary>Gets the ....</summary>
/// <remarks>This is what is available to outside clients of the domain.</remarks>
public virtual IEnumerable<CategoryTranslated> CategoriesTranslated{ get { return _InternalCategoriesTranslated; } }
/// <summary>Workhorse property that maintains the set of translated categories by:
/// <item>being available to <see cref="Category"/> to maintain data integrity.</item>
/// <item>lazily instantiating the <see cref="List{T}"/> when it is needed.</item>
/// <item>being the property mapped to NHibernate, the private <see cref="_categoriesTranslated"/> field is set here.</item>
/// </list>
/// </summary>
protected internal virtual IList<Category> _InternalCategoriesTranslated
{
get { return _categoriesTranslated?? (_categoriesTranslated= new List<Category>()); }
set { _categoriesTranslated= value; }
}
private IList<StaffMember> _categoriesTranslated;
Now you need to set your mapping to access the private field, so assuming you use my casing preferences here, you'd have:
public void Override(AutoMapping<Category> mapping)
{
mapping.HasMany(x => x.CategoriesTranslated)
.Inverse()
.Access.CamelCaseField(CamelCasePrefix.Underscore)
.Cascade.All();
}
HTH,
Berryl
EDIT ============
The _Internal collection also gives the child of of the bi-directional relationship, CategoryTranslated in this case, a hook, as shown in the code below:
public virtual CategoryTranslated CategoryTranslated
{
get { return _categoryTranslated; }
set
{
if (_categoryTranslated!= null)
{
// disassociate existing relationship
_categoryTranslated._InternalCategoryTranslated.Remove(this);
}
_categoryTranslated= value;
if (value != null)
{
//make the association
_categoryTranslated._InternalCategoryTranslated.Add(this);
}
}
}
private CategoryTranslated _categoryTranslated;
Upvotes: 2