2

私は自家製のORMシステムをEntity Framework 4で置き換えたり補完したりすることを検討しています。私は、プログラミングコードの命名規則と定義したものの間に矛盾が生じることに気付いています。データベース。マイクロソフトのショップであるため、メンバー、名前空間などにパスケーシングを使用すると言われているMicrosoft's naming guidelines for our codeに従うことを主に決めました。アンダースコアの使用を避けるなどです。EF4のエンティティとデータベース標準の間の命名規則の競合の解決?

EF4のデフォルトのエンティティ命名規則は、驚くことではないが、これらの標準でうまく機能します。たとえば、SalesOrderというエンティティは、SalesOrderという名前のクラスと、SalesOrdersという名前のエンティティセットを生成します。 EF4モデル - ファーストデザインは、デフォルトでエンティティセットと同じ名前のテーブルを生成します(この例では、生成されたテーブル名はSalesOrdersです)。しかし、データベース標準では、単語間に小文字とアンダースコアを使用することを推奨しています(例:sales_orders)。したがって、Entity Frameworkを「そのまま」使用すると、私たちはそれらから逸脱し始めます。

エンティティ・セット名をSQLテーブル名として使用する動作をオーバーライドすることができるEntity Frameworkはどこにありますか?生成されたSQLスクリプトの代替テーブル名を指定する明白な場所を見つけることができないようです。 EF4を使用して前進する場合、データベース命名規則を再考する唯一のもっともらしい解決策はありますか?

更新:

私は以下のラディスラフのソリューションをしようとしているが、私はは私のカスタムユーティリティを認識するようにEntity Frameworkのモデルデザイナーでモデルオプションからデータベースを生成ように見えることはできません。

%VSINSTALLDIR%\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes 

それは基本的に次のようになります:

<#@ import namespace="Microsoft.CSharp"#> 
<#@ import namespace="System.Text"#> 


public class CustomUtilities 
{ 
    public static string EntityNameToSqlName(string name) 
    { 
     string sqlName = ""; // The table name based on the input model name 
     string pattern = "([A-Z]+[s])|([A-Z](?=[a-z]))|((?<=[a-z])[A-Z])"; //Pattern for the regex exp. below 

     // Separate out each word with spaces: 
     sqlName = System.Text.RegularExpressions.Regex.Replace(name, pattern, " $&"); 

     // Replace spaces with underscores and then make lowercase: 
     sqlName = sqlName.Trim().Replace(" ", "_").ToLower(); 

     return sqlName; 
    } 

} 

私は私の中でこのファイルを参照しようとした私は、フォルダにMyOrg.EF.Utility.CS.ttincludeという名前のファイルを持っています以下のようなトップの近くにカスタム.ttのDDL生成ファイル:

<#@ include file="MyOrg.EF.Utility.CS.ttinclude"#> 

しかし、私は、.ttファイルに次のようなコードを使用して上記の関数を参照しようとした場合:

string tableName = CustomUtilities.EntityNameToSqlName(Id(entitySet.GetTableName())); 

のVisual Studioは、名 'CustomUtilities' は現在のコンテキストに存在しないと文句を言い。 "CustomUtilities.EntityNameToSqlName"からクラス名を削除すると、同様のエラーが返されます。カスタム関数をDDL生成コードに挿入する別の方法を試すべきでしょうか?

最終的な解決策:

私は私MyOrg.EF.Utility.CSでのC#コードをラップしていないことに気づいた後、私は最終的にこの作業を取得することができました。これでttincludeファイル:

<#+ 
[my code] 
#> 

私もWriteColumns(のパブリックコピーを追加するために必要な)それは私のEntityNametoSqlName()メソッドを使用するようにファイルGenerateTSQL.Utilityで見つけ方法。私はそこにかなりの数のアイテムを中心にCustomUtilities.EntityNameToSqlName()をラップする必要があるため

残念ながら、オリジナルのSSDLToSQL10.ttファイルの私のカスタマイズされたバージョンは、今少し厄介です。

答えて

2

があります。あなたのモデルをSQL DDLスクリプトに変換するT4テンプレートがあります。このテンプレートのコピーを作成し、新しいコピーに名前生成のための独自のロジックを入れることができます。その後あなたは自分のデザイナー(DDL生成テンプレートのプロパティ)で、このテンプレートを設定する必要があり、モデルからデータベースを生成を実行...

あなたは、デフォルトのテンプレートがあります:

%VSINSTALLDIR%\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\DBGen\SSDLToSQL10.tt 
+0

これまでのところ私の最大の賭けと思われますが、辛いほど複雑です。 ** SSDLToSQL10.tt **ファイルのクローンをセットアップし、すべてのテーブル名を小文字にするために少し微調整しました。この新しいDDL生成テンプレートを使用して、自分のエンティティモデルのテーブルを生成することができました。その後、** [My Organization's Name] .EF.Utility.CSという名前のカスタムインクルードファイルを作成しました。ttinclude ** '%VSINSTALLDIR%\ Common7 \ IDE \ Extensions \ Microsoft \ Entity Framework Tools \ Templates \ Includes' しかし、私は上記の主な機能を参照することができないようです.ttファイル。 – Derek

+0

私の更新は、カスタムDDL生成テンプレートを使って試したことがあります。 – Derek

+0

ああ!私はそれが働いていた - 私は '<# >'と012の状態コードでC#コードを忘れていた – Derek

0

できます。関連するテーブルと関連する列でエンティティをマッピングするカスタムモデルビルダを実装する必要があります。 この関数をコンテキストクラスに追加することによって、OnModelCreating関数をオーバーライドしてカスタムモデルを構築することができます。

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
    modelBuilder.Entity<EntityName>().Map(c => c.ToTable("TableName"));//to map entity with table 
    modelBuilder.Entity<EntityName>().Property(s => s.Property).HasColumnName("ColomnName");//to map properties with colomns 
} 
+0

このコードはどこに挿入しますか?私はこのブログで非常によく似たものを見つけました: http://alensiljak.blogspot.com/2011/06/custom-table-mapping-with-entity.html しかし、これはコードファーストのアプローチを目指していますが、私は視覚的な人ではないので、Model-Firstアプローチを試しています。 – Derek

+0

次に、edmxデザイナーでそれを行うことができます。edmxダイアグラムであなたのエンティティを右クリックし、テーブルマッピングを選択します。そこでは、マッピングするテーブルとエンティティのプロパティの関連する列を選択できます。 –

+0

あなたはそれが簡単だろうと思うでしょう...しかし、そのようなテーブルマッピングを変更しようとすると、エンティティ名と一致するテーブル名しか表示されません。 (すでにデータベースに存在する既存のテーブルまたは新しいテーブル名のいずれか)。 – Derek

4

正しい解決策をデータベースの命名規則を変更することです。

なぜ尾が犬を揺らすべきですか?現代のプログラミングでは、ほとんどのアクションはデータベースではなくスケーラビリティの高いビジネス/サービス層で行われます。プログラマーは、両方のために機能する命名規則を使用する必要があります。また、これらのオブジェクトを日常的に使用するアプリケーション開発者のニーズに対応する必要があります。場合によっては、おそらくフロントエンドの開発者のニーズに対応する必要があり、他の部分ではサーバー側のニーズに対応する必要があります。

命名規則の全目的は、複雑さを軽減することです。しかしここで認められている解決方法は、あらゆる種類の複雑さをさらに実装することです。そして、他のすべてのORMは、この人工的な問題に対する独自の複雑な解決策を考え出す必要があります。

+0

良い点。私はこれが最も簡単な解決策であり、可能な限り実装することをお勧めします。しかし、私が上で提案した初期化したケースでは、私が取り組んでいるプロジェクトの前にデータベース標準が厳密に定義されていたため、標準を変更すると歴史的な製品と矛盾することになります。しかし、ある時点では、砂の中に隠喩を描き、変化が最善のものになるかどうかを検討する必要があります。プログラマーがデータベースを所有している場合、あなたが提案した変更はおそらく最良のものです。 – Derek

+0

私はあなたが言っていることを聞いています - そして、あなたが最初にポイントを上げることを感謝します。私はもっ​​と多くの人々がこの議論を見つけて体重を増やすことを望んでいます。私はこれが多くの無駄の源であると推測しています。私がブロガーであれば、私はそれについてブログしたいと思っていました。 – GeorgeBarker

+1

ORMのポイントは、一人の慣習に従ってではなく、定義どおりにマッピングを実行することです。 SQL開発者を持つ大規模なチームは、独自の慣習を持つSQLチームが「尻尾を揺らしている」とは確信しません。実際には、ORMは旧式のDALよりもStoreに密接にバインドされているため、OO規則を満たすためにSQL名を採用する必要がある場合は、逆になります。個人的には同じコンベンションを避ける理由は見当たりませんが、もしそれらを同じにする必要があれば、非常に長い名前の依存関係を作り、SOCを壊しています。 – shannon

関連する問題