2017-06-28 11 views
3

私はEntity Framework 6 Code Firstを使用して、大きなPOCOモデルをデータベースに格納しています。モデルは1000sのプロパティを持ちます(lol **を要求しません)。つまり、複数のSQLテーブルに分割する必要があります(列の制限は1024です)。個別にプロパティを指定しなくても、これを行うにはどのような方法があります場合、私は思ったんだけどエンティティフレームワークをプログラムで複数のテーブルに分割する

modelBuilder.Entity<HugeEntity>.Map(m => 
{ 
    m.Properties(e => new { e.Prop1, e.Prop2 }); 
    m.ToTable("HugeEntity1"); 
}.Map(m => 
{ 
    m.Properties(e => new { e.Prop3, e.Prop4 }); 
    m.ToTable("HugeEntity2"); 
}; 

:私は、これは、通常そのような個々の列を指定することによって行われている知っています。理想的には、与えられた列の限界(つまり、1000)に基づいてエンティティを自動的に分割することができます。

標準的な方法がない場合でも、これを動作させるには最も簡単なハッキングは何ですか?モデルのプロパティは変更される可能性がありますので、複数の場所で完全にリストすることは避けてください。

アドバイスありがとうございます。

** CONTEXT:ドメインモデルで、特定のWebページでキャプチャする必要があるユーザー入力データを表します。 WebAPIにも公開されています。私のチームはキーとバリューのペアのアプローチを検討しましたが、WebAPIにヒットした将来のBIアプリケーションがデータを消費するのが難しくなると判断しました。

+0

リフレクションは可能な限りハックとして心に浮かびます。プロパティをループし、テーブル間で等しく分割します。これを行うための「適切な」方法があるかどうかはわかりません。 –

+2

私はその人になり、 "尋ねる"つもりです。 –

+0

できれば、ドキュメントストアデータベース(例としてmongoDB)を調べるとよいでしょう。これらのオブジェクトは、各オブジェクトが独立したスキーマを持つことができる場合に優れています。 – gunr2171

答えて

1

これを行う方法がわかりました。私はLinq式と "動的"キーワードを使用しなければなりませんでした。

private static void SplitIntoTables<T>(DbModelBuilder modelBuilder, IReadOnlyCollection<PropertyInfo> properties, int columnLimit) where T : class 
    { 
     var numberOfTables = Math.Ceiling((properties.Count + (double)columnLimit/2)/columnLimit); 
     var paramExp = Expression.Parameter(typeof(T)); 

     var tableIndex = 0; 
     foreach (var tableGroup in properties.GroupBy(p => p.Name.GetHashCode() % numberOfTables)) 
     { 
      var expressions = tableGroup.Select(p => Expression.Lambda(
       typeof(Func<,>).MakeGenericType(typeof(T), p.PropertyType), 
       Expression.Property(paramExp, p), paramExp)); 

      modelBuilder.Entity<T>().Map(m => 
      { 
       foreach (var exp in expressions) 
       { 
        m.Property((dynamic) exp); 
       } 
       m.ToTable($"{typeof(T).Name}_{++tableIndex}"); 
      }); 
     } 
    } 
+0

上記の私の以前のコメントであなたの回答が見られませんでした。私がそこに「動的」と書いたとき、私はそのキーワードに言及していませんでした。 [動的](https://stackoverflow.com/questions/31859016/is-the-use-of-dynamic-considered-a-bad-practice)キーワードを使用するベストプラクティスについての情報があります。 – pwilcox

+0

これは滑らかです。 Thx for sharing :-) – t3chb0t

+0

'p.Name.GetHashCode()%numberOfTables'なぜここでハッシュコードを使用していますか?これは別のトリックですか? – t3chb0t

2

あなたは私たちに「尋ねないでください」と言います。しかし、あなたの最大の問題は、あなた自身にそれを言っているということです。あなたのモデルが50以上のフィールドを持つようになると、何が起こっているのかを尋ねる必要があります。私は、息を飲んでコンピューティングのいくつかのより抽象的な概念を再訪する価値がないのだろうかと思います。私はDatabase Normalizationから始めます。 1Kの動的プロパティは、あなたがこれを必然的に必要としていることを私に伝えます。

ところで、「データベース正規化」の概念は、SQLデータベースそのものに固有のものではありません。できるだけ同じ場所でPOCOモデルを正規化する必要があります。確かに、OO言語にはいくつかの非リレーショナル概念があります。しかし、あなたが描いている極端な言い訳はありません。

もう1つのパラダイムはDomain Driven Designです。私は自分でそれほど流暢ではないので、私はあなたがそこから始めなければならないと言っているわけではありません。しかし、私がそれを実装する際の初めから、学習曲線は価値があったと言いたいと思います。

私は念頭に置かないでください。私は自分のテーブルを自分で最高の普通の形にしているわけではありません。しかし私は、私がしていない分野では、頭痛が強いことを伝えます。

+0

あなたは私の票をすでに手に入れていますが、あなたの最大の問題はあなた自身にそれを言っているということです。私はOPがデザインに疑問を投げかけているのではなく、そのことを回避しようとしています。おそらくほんのわずかの列を持つ行として保存できるプロパティです。 – t3chb0t

+0

元の投稿にいくつかのコンテキストを追加しました。それで、私は、あなたがまだ再設計が必要であると強く感じるかどうかを知りたいのです。 –

+0

いいえ、本当にありません。私が言っている唯一のことは、実際にはすでに実稼働環境にある場合はもちろん、デザインをしっかりと生きていて、転送は慎重に行わなければならないということです。また、Key-Valueのアプローチには、チームが検討したものよりも他の短所があります。 IDEを犠牲にして、ある変更が他の従属オブジェクトでうまく動かないことを伝えません。だから、それをあまりにも自由に使うという習慣に入らないでください。 – pwilcox

関連する問題