Fluent nhibernate多对一反向返回错误

时间:2014-10-24 19:50:49

标签: c# nhibernate fluent-nhibernate

我已经谷歌搜索了一段时间,现在试图理解nHibernate所以我可以自己解决它但是已经很短了。所以我来自Entity Framework v1,我们在其中编写一个select语句,如:

from query in context.Users.Include("Orders") where query.UserId == id select query;

或类似的地方,你会得到结果,说它是一个名为FoundUsers的局部变量,如果我想加载一个引用,就会编写一个Extension方法来加载引用,如果它没有被加载:

FoundUsers.Orders.LoadIfNotLoaded()

然后我们可以访问FoundUsers.Orders。有了这样说,你可以看到我以前的心态,这是我目前的Fluent NHibernate设置:

public class Clan
{
    public virtual int Clan_Id { get; set; }
    [Simple properties]
    public virtual IList<Match> Matches { get; set; }
}


public class Match
{
    public virtual int Match_Id { get; set; }
    [Simple properties]
    public virtual Clan Clan { get; set; }
}

以下是映射文件:

public class ClanMap : ClassMap<Clan>
{
    public ClanMap()
    {
        Id(x => x.Clan_Id).Column("Clan_Id").Not.Nullable();
        HasMany(x => x.Matches).Table("Matches").KeyColumn("Clan_Id").LazyLoad();
        Table("Clans");
    }
}

public class MatchMap : ClassMap<Match>
{
    public MatchMap()
    {
        Id(x => x.Match_Id).Column("Match_Id").Not.Nullable();
        [simple properties]
        References(x => x.Clan).Column("Clan_Id").LazyLoad();
        Table("Matches");
    }
}

这是我的查询声明:

public static Clan FindClanByName(string name)
    {
        ISessionFactory mySessionFactory = DatabaseUtilities.GetSessionFactory();
        using (ISession mySession = mySessionFactory.OpenSession())
        {
            using (mySession.BeginTransaction())
            {
                var find = mySession.QueryOver<Clan>().Where(t => t.Clan_Name == name).List<Clan>();
                mySession.Transaction.Commit();

                if (find != null && find.Count == 1)
                    return (Clan)find[0];
                else
                    return null;
            }
        }
    }

当我去访问返回的Clan的匹配列表时,我收到以下错误:

{"Initializing[Counter.Strike.Database.Clan#1]-failed to lazily initialize a collection of role: MyDatabase.Clan.Matches, no session or session was closed"}    NHibernate.HibernateException {NHibernate.LazyInitializationException}

我必须尝试过几种不同的映射方法,但没有一种方法可行。有些人给了我这个错误,有些人刚刚返回了一条(第一条)记录(数据库中有6条记录应该返回)。我希望能够访问与Clan相关联的匹配列表,然后是与每个匹配相关联的MatchStats列表(本文中未详细说明,但我确定我可以弄清楚我是否在右侧推送这个决议的方向)。谢谢!

更新1: 我在Clan类中添加了一个构造函数来初始化IList并将我的映射更改为:

HasMany(x => x.Matches).Inverse().Cascade.All();

References(x => x.Clan);

我也改变了我的findclanbyname函数,就像这样:

var find = mySession.QueryOver<Clan>().Where(t => t.Clan_Name == name).List<Clan>();
mySession.Transaction.Commit();

if (find != null && find.Count == 1)
    return find[0];
else
    return null;

当我逐步执行FindClanByName方法时,我可以在设置断点时看到加载的匹配项,并观察“找到”&#39;变量。一旦该方法返回到调用函数,我将丢失对匹配的引用,并且我得到上述错误。有什么想法吗?

更新2:只是想说nHibernate项目与调用函数位于不同的项目/命名空间中。我正在创建一个围绕nHibernate的包装器。

更新3:我认为这可能是因为我将离开使用声明的可见性。关于如何在会话之外维护引用的任何想法?

1 个答案:

答案 0 :(得分:0)

基于错误消息,您似乎在将实体框架知识转换为NHibernate知识时缺少的主要内容是&#34; session&#34;对应于。

EF的DbContext与NH Session大致相同。

我没有太多使用EF,但我想如果你在调用DbContext之前处理了LoadProperty,你会得到类似的错误,例如:

  

ObjectContext实例已被释放,不能再用于需要连接的操作。

那么,您是如何在Entity Framework项目中管理DbContext生命周期的呢?你可能应该在这个NHibernate项目中做类似的事情。例如,对于Web应用程序,您通常需要像每个Web请求一样的NHibernate会话。您可以在BeginRequest事件上打开会话,将其存储在HttpContext.Current.Items集合中,然后在EndRequest事件中处理Session。


你的第二个问题 - 只有在你预期六个时才会找回一条记录 - 这不是return (Clan)find[0]引起的吗?