1

何度か試みて検索した後、私はついにここでそれを試すことにしました。

短編小説:私はコンテンツ管理システムアプリケーション用にかなり「正規化された」データベース設計を作成しました。そして今、それをEFエンティティにマッピングしようとしています。

ここに画像の説明を入力してください

ページとそのコンテンツ(ContentVersionテーブル)の間にM:Nの関係があります-テーブルContentによって接続されています。これは、アプリケーションが多言語対応であり、コンテンツ編集の最近の履歴を保存するためです。

これで、dbからDbContextを作成し、いくつかのコントローラーをスキャフォールドして、しっかりとしたベースにすることができましたが、それには問題があります。新しいページを作成しようとすると、基本的にタイトルとスラッグだけを入力できますが、そのページのコンテンツはありません。もちろん、それを他のエンティティと接続して、毎回複数のエンティティを更新する階層的なビジネスロジックを作成することもできますが、最初はもう少し抽象的なアプローチを試してみたかったのです。

基本的に、3つの関連するテーブルに分割するエンティティが必要だと思います。ページを1つのピースとして操作するために使用できるエンティティ(FinalPageと呼びましょう)を作成したい->スキャフォールドコントローラーなどに使用します。

FinalPageは、ユーザーが新しいページを作成するときに入力するものであるため、次のものが含まれます。

Title(ページエンティティから)
Slug(ページエンティティから)
TemplateId(ページエンティティから)
LanguageId(Contentエンティティから)
Title(ContentVersionエンティティから)
Body(ContentVersionエンティティから)
+ContentVersionエンティティからの他の関連フィールド

そのための「新規作成」ページを生成すると、すべてが入力され、すべてが適切なテーブルに保存されます。

エンティティモデルに新しいエンティティを作成し、プロパティをさまざまなテーブルにマッピングしようとしました。いくつかのアプローチを試しましたが、うまくいく解決策は得られませんでした。主な理由は、「すべてのキーをマップする必要がある」という典型的なエラーです。私はRobBagbyからのこの投稿をチェックしていましたが、彼は同じキーを共有する2つのテーブルだけを接続していました。

また、本当にばかげていると感じたものを試しました... PageIdプロパティで接続されたPageエンティティとContentエンティティからエンティティ(entA)を作成します。そして、ContentとContentVersionから2番目(entB)を作成します-ContentIdによって接続されます。次に、entAとentBを接続する3番目(entC)を作成したいと思いました。それもうまくいきませんでした(そしてそれは本当に奇妙な解決策になるので、私は実際にうれしいです)。

私は次のように感じ
ます。a。)明らかな何かが欠けている。
b。)データベース設計が悪い。
c。)EFからあまりにも多くを望んでいます。

どんな助けでも歓迎します。
-データベースの設計にひどいことがあれば、教えてください。
-私の目標を達成する方法を知っているなら、共有してください。
-このタイプのアプリの経験があり、より良い解決策がある場合は、それについて聞きたいと思います。

また、基本的にいくつかのベストプラクティスを探しています。

4

2 に答える 2

3

ORM を UI モデルに合わせようとしているように聞こえますが、これはその方法ではありません。フォームから取得したいデータを表す新しいクラスを作成し、必要に応じてそれをさまざまなテーブルに処理する必要があります。したがって、新しいページを作成するときに使用されるモデルは次のようになります。

public class FinalPage{
    public string Title { get; set; }
    public string Slug { get; set; }
    public string Body { get; set; }
    public int TemplateId { get; set; }
    public int LanguageId { get; set; }
}

ユーザーがフォームを送信すると (使用している UI については言及していません)、それらの値をさまざまな ORM オブジェクトに処理します。

public void SaveData(FinalPage model){
    var page = new Page{
        Title = model.Title,
        ...
    };
    db.Pages.Add(page);

    var contentVersion = new ContentVersion{
        Body = model.Body,
        ...
    };
    db.ContentVersions.Add(contentVersion);

    ...
}

View Modelこれは aと aの違いでDatabase Modelあり、同じである必要はなく、ビジネス ロジックは 2 つのエンティティ間で適用されます。以前のプロジェクトで使用したこれに代わる方法は、使用する ORM オブジェクトを含むクラスを作成することです。この方法では、UI で DataAnnotation 検証を取得できます。

public class FinalPage{
    public Page Page { get; set; }
    public ContentVersion ContentVersion { get; set; }
    public Content Content { get; set; }
}

次に、各内部オブジェクトから適切なフィールドを表示します。Razor を使用した MVC4 の場合:

@Html.EditorFor(m=>m.Page.Title)

これにより、期待どおりの検証エラーが生成され、データ モデルで定義されますが、オブジェクトが後で正しく処理されるようにする必要がある場合があることに注意する必要があります (たとえば、MVC ではModelStateほとんどの場合無効になります) 。 . 個人的には、最初のアプローチをお勧めします。これは、異なる UI および ORM モデルを操作する従来の方法だからです。私が従う一般的なルールは、可能であれば ORM モデルを使用することですが、少しトリッキーになったらすぐに ViewModel クラスに切り替えて値を表現します。

于 2012-10-25T12:43:24.843 に答える