【问题标题】:Strange fluent nhibernate mapping for legacy application遗留应用程序的奇怪流畅的 nhibernate 映射
【发布时间】:2013-01-26 20:15:27
【问题描述】:

我们有一个遗留的 ASP.Net 项目,我们目前正在使用 MVP 模式对其进行重构。 对于后端,我们使用 Fluent NHibernate 和 oracle 数据库。 以前的开发人员直接在数据库中进行了奇怪的本地化实现。 而且我们很难用流畅的 nhibernate 映射它。

我们有以下表格,它们位于不同的数据库中。 (oracle 模式)

db1.Activity
(
  ID,               (pk)
  ID_LANGUAGENAME,  (fk)
  INPUT_DATE,
  and so on...
) 

db2.LanguageName
(
  ID,               (pk)
  ID_LANGUAGE,      (pk)
  NAME
)

db2.Language
(
  ID,
  LANGUAGE,
  LANGUAGE_SHORT
)

ID_LANGUAGE 存储在 ASP.Net 会话变量中。 我想映射实体,以便我可以执行类似此查询的操作。

SELECT LN.NAME, A.INPUT_DATE FROM db1.Activity A
INNER JOIN db2.LanguageName LN ON A.ID_LANGUAGENAME = LN.ID
INNER JOIN db2.Language L ON LN.ID_LANGUAGE = L.ID
WHERE A.ID = :ACTIVITYID AND L.ID = :LANGUAGEID_FROM_SESSION_VARIABLE

所以基本上我不想像这样的 Activity 实体:

public class Activity
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual DateTime InputDate { get; set; }
}

Activity 的名称自动映射到数据库中正确的 LanguageName.Name 字段。 NHibernate 甚至可以做到这一点吗?

【问题讨论】:

    标签: asp.net .net oracle fluent-nhibernate


    【解决方案1】:

    我不确定这是否是最好的方法

    <filter-def name="LanguageFilter">
      <filter-param name="activeLanguage" type="System.UInt32"/>
    </filter-def>
    
    <class name="Activity">
      <id name="Id"/>
    
      <many-to-one name="NameHolder" column="ID_LANGUAGENAME"/>
    
      <property name="InputDate"/>
    </class>
    
    <class name="ActivityName" tble="LanguageName">
      <id name="Id"/>
    
      <property name="Name"/>
      <filter name="LanguageFilter" condition=":activeLanguage = ID_LANGUAGE"/>
    </class>
    
    public class Activity
    {
        public virtual int Id { get; set; }
    
        protected virtual ActivityName NameHolder { get; set; }
        public virtual string Name
        {
            get { return NameHolder.Name; }
            set { NameHolder.Name = value; }
        }
    
        public virtual DateTime InputDate { get; set; }
    }
    

    并查询

    // at the beginning of the request
    s.EnableFilter("LanguageFilter").SetParameter("activeLanguage", Session["Language"]);
    
    var activity = session.QueryOver<Activity>()
        .Where(a => a.Id == activityId)
        .Single();
    
    Console.Writeline(activity.Name);
    

    【讨论】:

    • 这种方法有效,但是当我将 LanguageName 映射到 Activity 作为引用关系(1 到 1)时,有时我仍然会收到 NHibernate 异常,指出给定 id 有多个语言名称。因此,过滤器似乎并不总是适用。我应该全局设置过滤器的参数还是为我实现的每个存储库设置参数?
    • 必须在每个创建的 ISession 上设置过滤器,因为它仅应用于那个。此外,如果每个应用程序运行时 languageId 都是静态的,则可以在映射级别设置它,这将使其更加容易。
    猜你喜欢
    • 1970-01-01
    • 2010-11-22
    • 2023-03-14
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多