关于实体框架,NHibernate是否有类似的内容;s的导航属性?

关于实体框架,NHibernate是否有类似的内容;s的导航属性?,nhibernate,entity-framework,Nhibernate,Entity Framework,关于实体框架的导航属性,NHibernate上是否有类似的内容?例如,而不是: s.Save(new Product { Category = s.Get<Category>("FD"), Name = "Pizza" }); 我可以通知NHibernate不要使用产品的Category属性作为保存产品类别的机制吗?我想改用CategoryId(阅读:我不想使用DTO)。实体框架似乎能够帮助避免DTO模式,同时提供ORM的全部好处(可以使用导航属性避免连接)。我希望EF提供两全其美

关于实体框架的导航属性,NHibernate上是否有类似的内容?例如,而不是:

s.Save(new Product { Category = s.Get<Category>("FD"), Name = "Pizza" });
我可以通知NHibernate不要使用产品的Category属性作为保存产品类别的机制吗?我想改用CategoryId(阅读:我不想使用DTO)。实体框架似乎能够帮助避免DTO模式,同时提供ORM的全部好处(可以使用导航属性避免连接)。我希望EF提供两全其美(保存对象的精简机制,即不需要检索属性的对象)和查询内容的导航机制

来自EF的样本:


如果我理解您的问题,您希望在不点击数据库加载Category对象的情况下保存具有类别的产品。NHibernate绝对支持这一点,您几乎拥有正确的代码。以下是您在NHibernate中的操作方式:

s.Save(new Product { Category = s.Load<Category>("FD"), Name = "Pizza" });
s.Save(新产品{Category=s.Load(“FD”),Name=“Pizza”});
这不会命中数据库以获取实际类别,但只会使用正确的Category.Id保存产品。请注意,您不需要(我建议去掉Product.CategoryId)

现在,为什么这适用于session.Load(),而不适用于session.Get()。。。对于session.Get(),NHibernate必须返回对象或null。在.NET中,对象无法在事后用null替换自身。因此,NHibernate被迫转到数据库(或一级缓存)以验证“FD”类别是否确实存在。如果存在,则返回一个对象。否则,它必须返回null

让我们看看session.Load()。如果数据库中不存在该对象,则会引发异常。因此NHibernate可以从session.Load()返回代理对象,并延迟实际访问数据库。当您实际访问该对象时,NHibernate将检查数据库,如果该对象不存在,则可以在该点引发异常。在本例中,我们将产品保存到数据库中。NHibernate需要的只是类别的PK,它在代理中有PK。因此,它不必在数据库中查询Category对象。NHibernate永远不需要实际的类别对象来满足保存请求。

True,将s.Load(“FD”)与s.save一起使用,Sql Server探查器不会显示数据库中的任何类别命中。我更喜欢NHibernate谢谢你为我解释
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; }
}
// 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); 
Console.WriteLine("{0} {1}", c.CategoryId, c.Name);
s.Save(new Product { Category = s.Load<Category>("FD"), Name = "Pizza" });