首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate -延迟加载问题-Initializing[]-Could不初始化代理-没有会话。

NHibernate -延迟加载问题-Initializing[]-Could不初始化代理-没有会话。
EN

Stack Overflow用户
提问于 2011-09-28 13:49:46
回答 6查看 23.1K关注 0票数 9

嗨,我使用流利的NHibernate,我有点困惑的懒散加载。

database

  • modified对象properties

  • update数据库中的
  1. I查询对象

这是代码:

代码语言:javascript
复制
public class Credentials
{
    public virtual int Id { get; set; }
    public virtual string Nick { get; set; }
    public virtual string Password { get; set; }
}

public class CredentialsMap : ClassMap<Credentials>
{
    public CredentialsMap()
    {
        Id(x => x.Id);
        Map(x => x.Nick).Column("NICK");
        Map(x => x.Password).Column("PASSWORD");
        Table("R_CREDENTAILS");
    }
}

public class Status
{
    public virtual int Id { get; set; }
    public virtual string Msg { get; set; }
    public virtual DateTime AddTime { get; set; }
}

public class StatusMap : ClassMap<Status>
{
    public StatusMap()
    {
        Id(x => x.Id);
        Map(x => x.Msg).Column("MESSAGE");
        Map(x => x.AddTime).Column("ADD_TIME");
        Table("R_STATUS");
    }
}

public class Account
{
    public virtual int Id { get; set; }
    public virtual string SelfNick { get; set; }
    public virtual Credentials Credentials { get; set; }
    public virtual Status Status { get; set; }
}

public class AccountMap : ClassMap<Account>
{
    public AccountMap()
    {
        Id(x => x.Id);
        Map(x => x.SelfNick).Column("SELF_NICK");
        References(x => x.Credentials)
            .Column("CREDENTIALS_ID")
            .ForeignKey();
        References(x => x.Status)
            .Column("STATUS_ID")
            .ForeignKey();
        Table("R_ACCOUNTS");
    }
}

NHibernate配置类:

代码语言:javascript
复制
public class NHiberanteHelper
{
    private static ISessionFactory _sessionFactory;

    private static ISessionFactory SessionFactory
    {
        get
        {
            if (_sessionFactory == null)
                InitializeSessionFactory();

            return _sessionFactory;
        }
    }

    private static void InitializeSessionFactory()
    {
        _sessionFactory = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2008
                          .ConnectionString(
                               @"Server=TEST\SQLEXPRESS;Database=SimpleNHibernate;Trusted_Connection=True;").
                               ShowSql()
                              )
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Account>().Conventions.Add( DefaultCascade.All()))
            .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(true, true))
            .BuildSessionFactory();
    }

    public static ISession OpenSession()
    {
        return SessionFactory.OpenSession();
    }
}

以下是用法:

代码语言:javascript
复制
    public class LoginDbHelper
    {
        public static Account GetAccount(string nick)
        {
            using (var session = NHiberanteHelper.OpenSession())
            {
                var account = (session.QueryOver<Account>()
                    .JoinQueryOver<Credentials>(a => a.Credentials)
                    .Where(c => c.Nick == nick));

                if (account != null)
                    return account.SingleOrDefault();

                return null;
            }
        }

        public static void SaveOrUpdateAccount(Account account)
        {
            using (var session = NHiberanteHelper.OpenSession())
            {
                using (var trans = session.BeginTransaction())
                {
                    session.SaveOrUpdate(account);
                    trans.Commit();
                }
            }
        }
   }

问题代码:

代码语言:javascript
复制
var actualAccount = LoginDbHelper.GetAccount(nick);

//modify
actualAccount.Status.Msg = "New status 2";
actualAccount.Status.AddTime = DateTime.Now;


LoginDbHelper.SaveOrUpdateAccount(account);

我知道这个错误:

代码语言:javascript
复制
{"Initializing[NHibernateSample1.Status#1]-Could not initialize proxy - no Session."}

StackTrace:

代码语言:javascript
复制
 at NHibernate.Proxy.AbstractLazyInitializer.Initialize() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Proxy\AbstractLazyInitializer.cs:line 113
   at NHibernate.Proxy.AbstractLazyInitializer.GetImplementation() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Proxy\AbstractLazyInitializer.cs:line 191
   at NHibernate.ByteCode.Castle.LazyInitializer.Intercept(IInvocation invocation) in d:\CSharp\NH\NH\nhibernate\src\NHibernate.ByteCode.Castle\LazyInitializer.cs:line 61
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.StatusProxy.set_Msg(String value)
   at NHibernateSample1.Program.Main(String[] args) in E:\C# PROJECTS\Samples\SimpleNHibernateClient\NHibernateSample1\Program.cs:line 215
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

I搜索它,我认为它是由延迟加载引起的,因为在GetAccount方法中,我关闭了会话。这是我第一次尝试使用NHibernate,所以如何才能正确地解决这个问题?如果是的话,可以禁用延迟加载,如何执行呢?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-09-28 13:56:39

你是对的。因为NHibernate会话是在GetAccount方法中关闭的(它仅在using语句的作用域中打开),所以不能在此方法之外加载其他对象。有两个潜在的解决办法:

  1. 在操作级别创建会话(即在包含问题代码的方法中),然后在get &
  2. 方法中使用该会话。您可以通过将会话作为参数传递给methods.
  3. Change (对象不使用延迟加载)来使用它。您可以通过在fluent映射中将.Not.LazyLoad()添加到Status对象来做到这一点。
票数 11
EN

Stack Overflow用户

发布于 2011-09-28 22:45:21

我发现关闭延迟加载的最简单方法是添加一个DefaultLazy约定,即:

代码语言:javascript
复制
.Conventions.Add( DefaultCascade.All(), DefaultLazy.Never() )

注意,根据应用程序的不同,打开延迟加载(DefaultLazy.Always())确实可以提高性能。

缺点是,在延迟加载实体中的其余数据之前,总是必须打开会话。在我的经验中,支持延迟加载的会话管理是NHibernate最大的痛苦之一。

票数 5
EN

Stack Overflow用户

发布于 2011-09-28 14:01:16

在LoginDbHelper.GetAccount(.)中打开和关闭会话方法。

尝试在方法之外创建和打开会话,并将其作为方法param传递,例如:

代码语言:javascript
复制
    // method
    public static Account GetAccount(string nick, ISession session) 
    {   
     var account = (session.QueryOver<Account>().JoinQueryOver<Credentials>(a => a.Credentials).Where(c => c.Nick == nick));   

           if (account != null)                      
            return account.SingleOrDefault();                    
    return null;  
    }

// usage
    var actualAccount = LoginDbHelper.GetAccount(nick);   
    actualAccount.Status.AddTime = DateTime.Now;   
    using (var session = NHiberanteHelper.OpenSession())  

    LoginDbHelper.SaveOrUpdateAccount(account, session); 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7584315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档