以下を完了するための最もクリーンでベストプラクティスの方法を決定しようとしています。
私は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);
}