1

いくつかのプロパティといくつかのメソッドを持つクラスがあります

public class Content
{
    public int Id { get; set; }
    public string Application { get; set; }
    public string Property1 { get; set; }
    public string Property2 { get; set; }

    public override bool Equals(object obj) {...}
    public override int GetHashCode() {...}
}

この Fluent NHibernate マッピングを使用すると、次のようになります。

public class ContentMapping : ClassMap<Content>
{ 
   public ContentMapping()
   {
      Table("vw_all_contents");

      CompositeId()
                .KeyProperty(x => x.Id, "id")
                .KeyProperty(x => x.Application, "application");

      Map(x => x.Property1, "property1");
      Map(x => x.Property2, "property2");
   }
}

ここまではすべて正常に動作します。

同じオブジェクトにデータを入力したいのですが、別のデータベースに接続するフェデレーテッド テーブルを使用します。

ので、私は持っています:

public class ContentOnProductionDatabase : Content { }

マッピングの場合:

public class ContenOnProductionDatabasetMapping : ClassMap<ContentOnProductionDatabase>
{ 
   public ContentOnProductionDatabaseMapping()
   {
      Table("vw_federated_all_contents");

      CompositeId()
                .KeyProperty(x => x.Id, "id")
                .KeyProperty(x => x.Application, "application");

      Map(x => x.Property1, "property1");
      Map(x => x.Property2, "property2");
   }
}

そして、ここで NHibernate が本当に混乱し、クエリが両方のデータベースから混合した結果を返します。

ContentOnProductionDatabase が Content を拡張せず、代わりに次のような重複クラスである場合、問題は解決します。

public class ContentOnProductionDatabaseMapping
{
    public int Id { get; set; }
    public string Application { get; set; }
    public string Property1 { get; set; }
    public string Property2 { get; set; }

    public override bool Equals(object obj) {...}
    public override int GetHashCode() {...}
}

だから今はすべて問題ありませんが、コードの重複が非常に多いという事実は好きではありません.NHibernateに継承を無視させ、2つを区別させるには、何らかのマッピング構成が必要です。異なるデータベースにマップします。

リポジトリ フレームワークは組み込みのフレームワークで、セッションとクエリを処理します。

public class ContentRepository : NHibernateRepositoryBase, IContentRepository
{
    public ContentRepository(INHibernateContext context, ISettingsManager settingsManager): base(context){   }

    public Content ReadContent(int id, string application)
    {
        using (ISessionContainer container = Context.GetSessionContainer())
        {
            return
                container.AsQueryable<Content>()
                    .FirstOrDefault(c => c.Id == id && c.Application == application);
                    // All queries using <Content> return the correct results
        }
    }

    public ContentOnProductionDataBase ReadFederatedContent(int id, string application)
    {
        using (ISessionContainer container = Context.GetSessionContainer())
        {
            return
                container.AsQueryable<ContentOnProductionDataBase>()
                    .FirstOrDefault(c => c.Id == id && c.Application == application);
                    // All queries using <ContentOnProductionDataBase> return the combined results of <Content> and <ContentOnProductionDataBase>
        }
    }
}

内部的に、container.AsQueryable はこれを呼び出すことで機能します:

public IQueryable<TEntity> AsQueryable<TEntity>() where TEntity : class
{
  return LinqExtensionMethods.Query<TEntity>(this.Session);
}

コードの重複を取り除く方法はありますか?

4

1 に答える 1