实体框架包括属性和存储库模式

时间:2018-01-24 22:12:03

标签: c# entity-framework-core repository-pattern

我有一个包含表论坛和主题的数据库。每个主题都有一个外键到其父论坛。

他们关联的C#模型是论坛和主题,论坛有一个指向其子主题的ICollection。我有一个论坛存储库,我用它来直接访问实体框架的上下文,我只返回它的Forum / IEnumerable。应用程序的其余部分仅通过此存储库访问数据库。我的问题如下:在某个时间点,我想从数据库中获取所有论坛而不填充“主题”属性。要做到这一点,我必须有一个GetAll方法来执行此操作:return _context.Forums.ToList();.

但是现在假设我还希望在某些时候返回所有论坛,但是填充了他们的Topics属性。我想我可以在存储库中创建一个新方法(称为GetAllForumsWithTopics或其他东西),但每次我想要包含更多字段时创建一个新方法似乎很奇怪(可能在某些时候我也希望包含该主题的属性) ,说它的帖子列表..然后我必须像GetAllForumsWithTopicsWithPosts一样?)。

所以,我想以某种方式定义方法GetAllForums(" includelist")[编辑:我实际上不喜欢字符串作为参数,但是lambda表达式:) ]方法,允许我在层次结构中包含属性(不仅仅是论坛本身)。这样做的好方法是什么?

2 个答案:

答案 0 :(得分:2)

写出你试图做的代码可能是一个好主意。我读这篇文章的方式是你有以下内容:

public class Forum
{
    public int Id {get; set;}
    public IEnumerable<Topic> Topics {get; set;}
}

public class Topic
{
    public int Id {get; set;}
    public Forum Forum {get; set;}
}

有几种方法可以解决这个问题。听起来你已经知道虚拟和非虚拟之间的区别,当谈到加载内容的渴望时。您可以使用Include属性选择性地包含子元素(请参阅:https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx

就个人而言,我可能接近这个的路线是在我的EF实现类中(实现了在别处使用的接口)有两个get方法:

public virtual IQueryable<Forum> Forums => _context.Forums;
public virtual IQueryable<Forum> ForumsWithChildren => _context.Forums.Include(m => m.Topic)

在“真实世界”的应用程序中,应该有一个时间限制器,并且只通过特定的论坛调用来提取主题:

public virtual Forum GetForumWithRecentPosts(int id)
{
    //Add where clause to restrict based off date.
    return Forums.Where(x => x.Id == id).include(m => m.Topic);
}

答案 1 :(得分:1)

您可以创建一个重载,它接受要包含的内容的表达式。

var forumsWithTopics = _forumRepository(q => q.Topics).ToList();

并像这样使用它:

const string cExcelPropertyPlacement = "Placement"