我刚刚从EF5切换到NHibernate,因为我想在ORM中使用一些功能,但在EF中找不到。所以,我是NHibernate的新手。我在ASP.Net MVC工作。
我正在使用Automapper将FNH对象映射到我的视图模型,但是我之前在将EF中的事情转换为FNH时遇到了问题。例如,我有一个自引用表,它是一个菜单系统。
以下是模型:
public partial class Menu {
private int _Id;
private string _Title;
private string _Link;
private int _SortOrder;
private System.Nullable<int> _ParentMenuId;
private Iesi.Collections.ISet _ChildMenus;
private Menu _ParentMenu;
#region Extensibility Method Definitions
partial void OnCreated();
#endregion
public Menu()
{
this._ChildMenus = new Iesi.Collections.HashedSet();
OnCreated();
}
/// <summary>
/// There are no comments for Id in the schema.
/// </summary>
public virtual int Id
{
get
{
return this._Id;
}
set
{
this._Id = value;
}
}
/// <summary>
/// There are no comments for Title in the schema.
/// </summary>
public virtual string Title
{
get
{
return this._Title;
}
set
{
this._Title = value;
}
}
/// <summary>
/// There are no comments for Link in the schema.
/// </summary>
public virtual string Link
{
get
{
return this._Link;
}
set
{
this._Link = value;
}
}
/// <summary>
/// There are no comments for SortOrder in the schema.
/// </summary>
public virtual int SortOrder
{
get
{
return this._SortOrder;
}
set
{
this._SortOrder = value;
}
}
/// <summary>
/// There are no comments for ParentMenuId in the schema.
/// </summary>
public virtual System.Nullable<int> ParentMenuId
{
get
{
return this._ParentMenuId;
}
set
{
this._ParentMenuId = value;
}
}
/// <summary>
/// There are no comments for ChildMenus in the schema.
/// </summary>
public virtual Iesi.Collections.ISet ChildMenus
{
get
{
return this._ChildMenus;
}
set
{
this._ChildMenus = value;
}
}
/// <summary>
/// There are no comments for ParentMenu in the schema.
/// </summary>
public virtual Menu ParentMenu
{
get
{
return this._ParentMenu;
}
set
{
this._ParentMenu = value;
}
}
}
这是映射:
public class MenuMap : ClassMap<Menu>
{
public MenuMap()
{
Schema(@"dbo");
Table(@"Menus");
LazyLoad();
Id(x => x.Id)
.Column("Id")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Identity();
Map(x => x.Title)
.Column("Title")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar");
Map(x => x.Link)
.Column("Link")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Not.Nullable()
.Length(50);
Map(x => x.SortOrder)
.Column("SortOrder")
.CustomType("Int32")
.Access.Property()
.Generated.Never()
.Not.Nullable()
.UniqueKey("KEY1");
Map(x => x.ParentMenuId)
.Column("ParentMenuId")
.CustomType("Int32")
.Access.Property()
.Generated.Never()
.UniqueKey("KEY1");
HasMany<Menu>(x => x.ChildMenus)
.Access.Property()
.AsSet()
.Cascade.None()
.LazyLoad()
.Inverse()
.Not.Generic()
.KeyColumns.Add("ParentMenuId", mapping => mapping.Name("ParentMenuId")
.SqlType("int")
.Nullable());
References(x => x.ParentMenu)
.Class<Menu>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Columns("ParentMenuId");
}
}
这是我的View Model或DTO:
public class MainMenuItemViewModel
{
public Int32 Id { get; set; }
public string Title { get; set; }
public string Link { get; set; }
public Int32 SortOrder { get; set; }
public Int32? ParentMenuId { get; set; }
public IList<MainMenuItemViewModel> ChildMenus { get; set; }
}
当我尝试将域对象映射到视图模型时,使用:
Mapper.CreateMap<Menu, MainMenuItemViewModel>();
我收到以下错误,我检查配置是否在运行时有效:
The following property on WinStream.WebUI.Models.MainMenuItemViewModel cannot be mapped: ChildMenus
Add a custom mapping expression, ignore, add a custom resolver, or modify the destination type WinStream.WebUI.Models.MainMenuItemViewModel.
Context:
Mapping to property ChildMenus from System.Object to WinStream.WebUI.Models.MainMenuItemViewModel
Mapping to property ChildMenus from Iesi.Collections.ISet to System.Collections.Generic.IList`1[[WinStream.WebUI.Models.MainMenuItemViewModel, WinStream.WebUI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
Mapping from type WinStream.Services.Entities.Menu to WinStream.WebUI.Models.MainMenuItemViewModel
Exception of type 'AutoMapper.AutoMapperConfigurationException' was thrown.
我认为这可能与将ISet转换为IList有关,所以我在我的视图模型中放入了一个ISet,但仍然存在问题。
感谢您的帮助 - 我意识到这可能是一个完整的新手问题,但我无法通过Google找到很多帮助。我已经好好忍受了好几天了。
谢谢!
修改
我已经超过了上面的错误,但现在当我查询数据库时,根对象的ChildMenus集合包含数据库中每个子对象的空对象,包括关联的子对象,而不仅仅是实际相关的子对象。
例如:
这是代码:
IList<Menu> menus = session.Query<Menu>().Where(x => x.ParentMenuId== null).ToList()
有关此问题的任何想法,还是我需要将其置于另一个问题?谢谢!
答案 0 :(得分:2)
NHibernate不需要很多EF的解决方法。您基本上有一个菜单,其中包含具有父参考的有序子菜单。
public class Menu
{
public int Id { get; protected set; }
public string Title { get; set; }
public string Link { get; set; }
public IList<Menu> ChildMenus { get; protected set; }
public Menu ParentMenu { get; set; }
public Menu()
{
ChildMenus = new List<Menu>();
}
}
public class MenuMap : ClassMap<Menu>
{
public MenuMap()
{
Table(@"Menus");
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.Title).Length(100);
Map(x => x.Link).Length(50);
HasMany<Menu>(x => x.ChildMenus)
.AsList("SortOrder")
.Inverse()
.KeyColumn("ParentMenuId");
References(x => x.ParentMenu).Column("ParentMenuId");
}
}
注意:
parentId与Parent.Id重复,可在需要时实施ParentId { get { return ParentMenu == null ? null : (int?)ParentMenu.Id } }
,无需在字段中映射或存储
如果不需要父引用,请从集合映射中删除它并.Inverse()