我正在寻找完成以下任务的最干净/最佳实践方式:
我正在使用 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() }}
}
或者,我正在考虑在控制器中填充 TagCount 属性,调用 TagRepository 中的方法,例如:
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 的回答的解决方案是执行以下操作:
- 我没有创建一个全新的类,而是继承了我正在扩展的类: 注意:我必须创建一个附加属性 TagsView 因为我无法覆盖 Scientific : Project 类的虚拟属性。
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;
}
-更新全部从控制器执行。感谢您提供优秀 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);
}