Hao*_*Hao 3 nhibernate entity-framework
关于Entity Framework的导航属性,NHibernate是否有类似的东西?例如,而不是:
s.Save(new Product { Category = s.Get<Category>("FD"), Name = "Pizza" });
Run Code Online (Sandbox Code Playgroud)
我希望我能写:
s.Save(new Product { CategoryId = "FD", Name = "Pizza" });
Run Code Online (Sandbox Code Playgroud)
我可以告知NHibernate不要使用Product的Category属性作为保存Product类别的机制吗?我想改用CategoryId(阅读:我不想使用DTO).实体框架似乎能够完全避免DTO模式,同时提供ORM的全部好处(可以避免使用导航属性进行连接).我希望EF提供两全其美(用于保存对象的精益机制,即无需检索属性的对象)和用于查询内容的导航机制
来自EF的样本:http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-code-first-walkthrough.aspx
public class Category
{
public virtual string CategoryId { get; set; }
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
}
public class Product
{
public virtual int ProductId { get; set; }
public virtual string Name { get; set; }
public virtual string CategoryId { get; set; }
public virtual Category Category { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
[UPDATE]
关于James的回答,我试着在SQL Server Profiler中看到NHibernate的动作.
// this act didn't hit the Category table from the database
var c = s.Load<Category>("FD");
// neither this hit the Category table from the database
var px = new Product { Category = c, Name = "Pizza" };
// this too, neither hit the Category table from the database
s.Save(px);
Run Code Online (Sandbox Code Playgroud)
只有当您实际访问NHibernate将访问数据库的Category对象时
Console.WriteLine("{0} {1}", c.CategoryId, c.Name);
Run Code Online (Sandbox Code Playgroud)
如果我理解您的问题,您希望保存具有类别的产品,而无需访问数据库以加载Category对象.NHibernate绝对支持这一点,你几乎拥有正确的代码.以下是NHibernate中的操作方法:
s.Save(new Product { Category = s.Load<Category>("FD"), Name = "Pizza" });
Run Code Online (Sandbox Code Playgroud)
这不会命中数据库来获取实际的类别,但它只会保存具有正确Category.Id的产品.请注意,您不需要(我建议删除Product.CategoryId).
现在为什么这适用于session.Load(),而不是session.Get()...对于session.Get(),NHibernate必须返回对象或null.在.NET中,事件之后,对象无法用null替换自身.因此NHibernate被迫转到数据库(或L1缓存)来验证"FD"类别实际存在.如果存在,则返回一个对象.如果不是,则必须返回null.
我们来看看session.Load().如果数据库中不存在该对象,则会引发异常.因此NHibernate可以从session.Load()返回一个代理对象,并延迟实际访问数据库.当您实际访问该对象时,NHibernate将检查数据库,如果该对象不存在,则可以在该点抛出异常.在这种情况下,我们将产品保存到数据库中.所有NHibernate需求都是Category的PK,它在代理中有.因此,它不必在数据库中查询Category对象.NHibernate实际上从不需要为实际的Category对象提供水合以满足保存请求.
| 归档时间: |
|
| 查看次数: |
868 次 |
| 最近记录: |