【问题标题】:NHibernate BasicSample with Nhibernate 3.3NHibernate BasicSample 与 Nhibernate 3.3
【发布时间】:2012-08-17 14:02:21
【问题描述】:

我开始了一个新项目,对于这个项目,我想使用 BasicSample(NHibernate 最佳实践,http://www.codeproject.com/Articles/13390/NHibernate-Best-Practices-with-ASP-NET-1-2nd-Ed)我以前没有使用过它,现在我遇到了问题。在这个项目中,我使用 NHibernate 3.3.1 并修改了 BasicSample 的源代码以使用我的实体。对于每个类模型,我都会收到此错误(仅显示类“月”):

System.TypeInitializationException was unhandled by user code

Message=“嵌套”的类型初始化程序引发了异常。 源=项目.数据 类型名称=嵌套 堆栈跟踪: 在 Project.Data\NHibernateSessionManager.cs:line 28 中的 Project.Data.NHibernateSessionManager.get_Instance() 在 App_Code\NHibernateSessionModule.cs:line 27 中的 Project.Web.NHibernateSessionModule.BeginTransaction(Object sender, EventArgs e) 在 System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 在 System.Web.HttpApplication.ExecuteStep(IExecutionStep 步骤,Boolean& completedSynchronously) 内部异常:NHibernate.InvalidProxyTypeException Message=以下类型不能用作代理: Project.Core.Domain.Calendar.Month:方法 Equals 应该是“公共/受保护的虚拟”或“受保护的内部虚拟” Project.Core.Domain.Calendar.Month:方法 IsTransient 应该是“公共/受保护的虚拟”或“受保护的内部虚拟” Project.Core.Domain.Calendar.Month:方法 get_Year 应该是“公共/受保护的虚拟”或“受保护的内部虚拟” Project.Core.Domain.Calendar.Month:方法 set_Year 应该是“公共/受保护的虚拟”或“受保护的内部虚拟” 块引用

类看起来像:

public class Month : DomainObject<int>
{
    private Year _year;
    public Year Year
    {
        get { return _year; }
        set { _year = value; }
    }

    private string _monthName; 
    public string MonthName
    {
        get { return _monthName; }
        set { _monthName = value; }
    }

    private IList<Consumption> consumptions = new List<Consumption>();
    public IList<Consumption> Consumptions
    {
        get { return new List<Consumption>(consumptions).AsReadOnly(); }
        protected set { consumptions = value; }
    }

    public Month()
    { }

    public override int GetHashCode()
    {
        return (GetType().FullName + "|" +
                MonthName.GetHashCode()).GetHashCode();
    }

有没有人知道问题出在哪里?我一直在交叉检查我的项目和 BasicSample 项目,但找不到任何不匹配的内容。

2. 谁能帮我解释一下如何使用 DaomainObject 中的 GetHashCode,因为我不知道如何在每个 1234562 中使用这个= 是否应该在此处添加类中的每个属性?

我希望有人可以帮助我。

【问题讨论】:

    标签: c# asp.net nhibernate c#-4.0


    【解决方案1】:

    问题包含在您的异常堆栈跟踪中。您需要更仔细地阅读它们:

    以下类型不能用作代理:
    Project.Core.Domain.Calendar.Month:方法 Equals 应该是“公共/受保护的虚拟”或“受保护的内部虚拟”
    Project.Core.Domain.Calendar.Month:方法 IsTransient 应该是“公共/受保护的虚拟”或“受保护的内部虚拟”
    Project.Core.Domain.Calendar.Month:方法 get_Year 应该是“公共/受保护的虚拟”或“受保护的内部虚拟”
    Project.Core.Domain.Calendar.Month:方法 set_Year 应该是“公共/受保护的虚拟”或“受保护的内部虚拟”

    它所说的基本上是,您需要将您班级的所有publicprotected 成员设为virtual,否则延迟加载将不起作用。


    GetHashCode:
    实例的哈希码在其生命周期内不应更改,因此不应包含可更改的属性。

    【讨论】:

    • 我将所有成员都公开为虚拟。然后我尝试作为示例项目..他们没有虚拟。我已经改回虚拟,但我仍然得到同样的错误。
    • @Thommie:我确定您没有收到 same 错误。您可能会发布新的调用堆栈。或者尝试自己仔细阅读并检查是否可以自己弄清楚。我假设DomainObject.IsTransient 仍然不是virtual
    • 我向您保证同样的错误。以下类型不能用作代理:('所有成员都是公共虚拟的) Project.Core.Domain.Calendar.Month:方法 Equals 应该是'公共/受保护的虚拟'或'受保护的内部虚拟' Project.Core.Domain .Calendar.Month:方法 IsTransient 应该是“公共/受保护的虚拟”或“受保护的内部虚拟” Project.Core.Domain.Calendar.Month:方法 get_Id 应该是“公共/受保护的虚拟”或“受保护的内部虚拟” Project.Core .Domain.Calendar.Month:方法 set_Id 应该是“公共/受保护的虚拟”或“受保护的内部虚拟”
    • @Thommie:你一定是在开玩笑吧 :-) 请比较两条错误消息。它们相同!
    • 对不起丹尼尔,它几乎是一样的!找到了。但不知道应该如何声明 equal 方法.. 现在它是 public override seal bool Equals(object obj)
    【解决方案2】:
    1. NHibernate 默认使用延迟加载。它通过从您的实体创建代理类来执行它 - 从您的实体继承并覆盖它的成员。为了使它起作用,您需要将所有实体成员标记为virtual。这就是它在异常消息中抱怨的内容。

    2. 至于GetHashCode,您应该在DomainObject 中实现它,并且只在GetHashCode 覆盖中使用Id。您还应该覆盖Equals。在这里您可以找到原因:NHibernate: Reasons for overriding Equals and GetHashCode

    【讨论】:

    • 我将所有成员都公开为虚拟。然后我尝试作为示例项目..他们没有虚拟。我已经改回虚拟,但我仍然得到同样的错误
    • 你的 DomainObject 应该有 Id 作为虚拟成员。那就是问题所在。以及 DomainObject 的其他成员。
    • 此外,在此期间,仅在 DomainObject 中覆盖 GetHashCode/Equals 就足够了。
    • 这应该是什么样子?public override seal bool Equals(object obj) { DomainObject compareTo = obj as DomainObject; return (compareTo != null) && (HasSameNonDefaultIdAs(compareTo) || // 由于 ID 不同,它们中的任何一个都必须是临时的,以便 // 比较业务价值签名 (((IsTransient()) || compareTo. IsTransient()) && HasSameBusinessSignatureAs(compareTo))); }
    • 是的,类似的...您检查空值,然后检查它们是否是临时的(未保存)并在这种情况下比较引用,最后检查它们的 id 是否相等。一个例子:blog.nerdbank.net/2006/01/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    相关资源
    最近更新 更多