我尝试使用Fluent Nhibernate在单个表中创建一个树。表必须如下所示:
模特课:
public class Category
{
public virtual int CategoryId { get; set; }
public virtual string CategoryName { get; set; }
public virtual Category ParentCategory { get; set; }
public virtual IList<Category> ChildCategory { get; } = new List<Category>();
}
映射类:
public class CategoryMap : ClassMap<Category>
{
public CategoryMap()
{
Id(x => x.CategoryId).GeneratedBy.Increment();
Map(x => x.CategoryName).Not.Nullable();
References(x => x.ParentCategory).Column("ParentCategoryId").Access.CamelCaseField();
HasMany(x => x.ChildCategory)
.Cascade.AllDeleteOrphan()
.AsSet()
.KeyColumn("CategoryId")
.Access.CamelCaseField();
}
}
ORM返回以下异常:
NHibernate.PropertyNotFoundException:找不到属性也没有 类'MyProj.Models.Category'中的字段'childCategory'
我只是在学习NH。我做错了什么?
答案 0 :(得分:1)
您不能将自动属性与字段访问策略一起使用。您需要一个明确的支持字段才能使其正常工作,其命名必须与您选择的命名策略相匹配。
因此,在您的情况下,将您的班级更改为:
public class Category
{
public virtual int CategoryId { get; set; }
public virtual string CategoryName { get; set; }
public virtual Category ParentCategory { get; set; }
private ISet<Category> childCategory = new HashSet<Category>();
public virtual ISet<Category> ChildCategory { get { return childCategory; } }
}
由于您要将其作为一个集合进行映射,我还为IList
更改了ISet
。
如果您想要支持字段的其他名称,请选择其他命名策略。有关hbm映射,请参阅here它们的列表。 (或get it in NHibernate reference documentation。)Fluent应该采用相同的策略。
您可以代替使用支持字段从映射中删除.Access.CamelCaseField()
,并在ChildCategory
属性中添加setter。
答案 1 :(得分:0)
我在以下内容中更改了映射类:
public class Category
{
private ISet<Category> childCategories;
private Category parentCategory;
public Category()
{
childCategories = new HashSet<Category>();
}
public virtual int CategoryId { get; protected set; }
public virtual string CategoryName { get; set; }
public virtual ReadOnlyCollection<Category> ChildCategories
{
get
{
return new ReadOnlyCollection<Category>(new List<Category>(childCategories));
}
}
public virtual Category ParentCategory
{
get
{
return parentCategory;
}
}
}
它是生成表,没有异常。