1

以下を完了するための最もクリーンでベストプラクティスの方法を決定しようとしています。

私はEF、コードファースト、リポジトリパターンを使用しています。Project という名前のエンティティがあり、プロジェクトを説明するタグまたはキーワードのリストがあります。

public class Tag {
   public int TagID { get; set; }
   public int ProjectID { get; set; }
   public string TagValue { get; set; }
}  

このデータを厳密に型指定された Razor ビューで使用しており、プロジェクト タイトルの下にタグを表示しています。これを行うとき、各タグに、データベースに表示される回数を次のように示します。

いくつかのプロジェクトのタイトル

C# (5)、エンティティ フレームワーク (17)

計算されたプロパティをエンティティに追加するのが最善の計画のように思えました。

public class Tag {
   public int TagID { get; set; }
   public int ProjectID { get; set; }
   public string TagValue { get; set; }
   public int TagCount { get { _context.Tags("Some Filter on TagValue").Count() }}
}

または、次のように TagRepository のメソッドを呼び出すコントローラーに TagCount プロパティを設定することを検討していました。

public int countTags(string TagValue);

ここで全体像を完全に見逃している可能性があることに気付いたので、私の質問は次のとおりです。これらのアプローチのいずれかが正しい方向に進んでいますか?

更新: 要求に応じてプロジェクト モデルを追加します。

アブストラクト プロジェクト:

public abstract class Project {
    public int ProjectID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

実施されたプロジェクトの種類:

public class Scientific : Project {
    public int ScientificProjectNumber { get; set; }
    public string FileNumber { get; set; }
    public int Year { get; set; }
    public DateTime StartDate { get; set; }

}

更新: Brian Cauthon の回答に基づく私の解決策は、次のことでした。

-まったく新しいクラスを作成する代わりに、拡張していたクラスを継承しました。 注: Scientific : Project クラスの仮想プロパティをオーバーライドできなかったため、追加のプロパティ TagsView を作成する必要がありました。

public class ScientificView : Scientific {
    public virtual ICollection<TagView> TagsView { get; set; }
}

- TagView についても同じことを行い、クラスをコピーするのではなく拡張しました。これらのオブジェクトが進化するにつれて、いくつかの労力が節約されることを願っています。

    public class TagView : Tag {
    public int TagCount { get; set; }
}

- 提案された TagRepository メソッドを追加しました:

public Dictionary<string, int> countTags(IEnumerable<string> tags) {
        Dictionary<string, int> result = new Dictionary<string, int>();
        var query = from o in _context.Tags
                group o by o.TagValue into tagGroup
                select new {TagText = tagGroup.Key,
                    TagCount = tagGroup.Count()};

        foreach (var tagGroup in query) {
            result.Add(tagGroup.TagText, tagGroup.TagCount);
        }
        return result;
    }

・Updateは全てControllerから実行。優れた AutoMapper プロジェクトへのリンクをありがとう:

public ViewResult Scientific(int projectID) {
        Scientific project= _scientificRepository.Scientific.FirstOrDefault(l => l.ProjectID == projectID);
        Dictionary<string, int> tagCounts = _tagRepository.countTags(project.Tags.Select(t => t.TagValue));

        Mapper.CreateMap<Scientific, ScientificView>();
        ScientificView sv = Mapper.Map<Scientific, ScientificView>(project);

        Mapper.CreateMap<Tag, TagView>();
        sv.TagsView = new List<TagView>();
        foreach (Tag t in project.Tags) {
            TagView tv = Mapper.Map<Tag, TagView>(t);
            tv.TagCount = tagCounts[tv.TagValue];
            sv.TagsView.Add(tv);
        }
        return View(sv);
    }
4

2 に答える 2

1

実際の質問については、個人的には、ビジネスロジックの実装方法を知ることはモデルのビジネスではなく、モデルのメソッドにビジネスロジックを実行させることだと思います。タグ数がモデルから外部で(つまり、ストアドプロシージャから)計算された場合、おそらく私はあなたが始めたルートをたどりますが、それを計算された列として定義します(ここで説明します

_context.Tags("").Count()ただし、各プロジェクトにロードされた各タグがこの呼び出しを実行するのと同じデータに対して何百回もデータベースを呼び出すことができるので、何を達成しようとしているのかが問題になる可能性があります。

于 2012-12-14T17:29:07.220 に答える
1

タグリポジトリからカウントを取得します。一度に複数のタグのカウントを取得する可能性が高いため、一度にすべてを取得するようにリポジトリメソッドを変更します。

私はあなたのビューのために特定のビューモデルを作成し、次にAutomapperを使ってあなたProjectTagそれらにマップします。

public class ProjectView {
    public int ProjectID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public virtual ICollection<TagView> Tags { get; set; }
}

public class ProjectTagView {
   public int TagID { get; set; }
   public string TagValue { get; set; }
   public int TagCount { get; set; }
}

次に、コントローラーに次のようなものがあります。

var model = AutoMapper.Map<Project,ProjectView>(project);
Dictionary<string,int> tagCounts = tagRepository.getCounts(model.Tags.Select(t=>t.TagValue));
foreach(var t in model.Tags){
    t.TagCount = tagCounts[t.TagValue];
}
于 2012-12-14T17:29:23.057 に答える