这是我的班级:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public ISet<User> Friends { get; set; }
}
这是我的映射:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="Test" assembly="test">
<class name="User" table="Users">
<id name="Id" column="id">
<generator class="native"/>
</id>
<property name="Name" column="name"/>
<set name="Friends" table="Friends">
<key column="user_id"/>
<many-to-many class="User" column="friend_id"/>
</set>
</class>
</hibernate-mapping>
这是问题所在:
User user = session.Load<User>(1);
User friend = new User();
friend.Name = "new friend";
user.Friends.Add(friend);
在最后一行[user.Friends.Add(friend)],我注意到它会在添加新朋友之前初始化Friends集合.
我的问题是:无论如何都要避免NHibernate中的这种行为?因为性能原因我只想要执行单个INSERT命令.
最佳答案 来自Hibernate.org
Why does Hibernate always initialize a collection when I only want to add
or remove an element?Unfortunately the collections API
defines method return values that may
only be computed by hitting the
database. There are three exceptions
to this: Hibernate can add to a ,
or declared with
inverse=”true” without initializing
the collection; the return value must
always be true.If you want to avoid extra database
traffic (ie. in performance critical
code), refactor your model to use only
many-to-one associations. This is
almost always possible. Then use
queries in place of collection access.
此外,阅读此博客条目NHibernate and Inverse=True|False Attribute,肯定会有所帮助.
将帖子
好吧,想想多对一和多对一.哪一个是同一个.这就是为什么他们说重构模型.你需要引入另一个实体,比如UserFriend或者其他东西.现在,您将为User-to-UserFriend,Friend-to-UserFriend进行多对一操作.
因此,正如您所看到的,这将使它成为多对多.我希望这能使重构事情变得清晰.您可能不想这样做,除非您遇到的是真实的糟糕表现.正如Darin已经提到的那样,其中一条评论认为,不要做预先成熟的优化.此外,我想引用Donald E. Knuth的臭名昭着的格言,“过早的优化是所有邪恶的根源”.