遗留应用程序的奇怪流畅的nhibernate映射

时间:2013-02-11 17:03:42

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

我们有一个传统的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来说甚至可能吗?

1 个答案:

答案 0 :(得分:2)

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

<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);