0

使用存储库模式和 ViewModels,如果您不希望原始数据库对象泄漏到存储库之外,如何针对数据库构建查询?如何在不将所有数据库加载到内存并使用 LINQ to Objects 的情况下实际创建查询?我不能将 IQueryable 暴露给应用程序的其余部分。

例如,使用 EF,我有一堆 POCO,其中有几个属性匹配 db 字段,但也有一些东西可以解决枚举不直接支持(目前)以及外键 ID 以防止 N+1 和更容易查询和很快。我不希望它们泄漏到应用程序的其余部分,我希望应用程序只看到一个普通的对象图。

public class DbUser
{
    public int Id { get; set; }
    public string Name { get set; }

    public int GroupId { get; set; }
    public DbGroup Group { get; set; }

    public ICollection<DbComment> { get; set; }
}

public class User
{
    public int Id { get; set; }
    public string Name { get set; }

    public Group Group { get; set; }
    public ICollection<Comment> { get; set; }
}

这里的问题是我的存储库将在内部使用 EF 进行查询(以及单元测试时的内存内容)。但我该如何实施IQueryable<User> FindAll()?我不能只做 return dbContext.Users.Select(u => new User(u)),因为在那种情况下我会失去所有可能的查询能力;它只会将整个用户集合加载到内存中,将所有类型从 DbUser 转换为 User,然后在内存集合上构建 LINQ 查询——这是非常低效的。

我不能只在存储库中构建查询。在某些页面上,我有选择一些字段的查询,但也从其他相关对象计算一些复杂的东西,根据结果过滤它们(例如具有正分数的评论计数),但我也需要在应用程序中返回。我可以选择所有用于获取复杂内容的对象并将它们返回给应用程序(但不是作为数据库实体),但这意味着选择大量数据。

基本上,我如何防止数据库实体用他们的垃圾和黑客行为污染应用程序的其余部分,同时仍然保持在存储库之外构建查询的能力

4

1 回答 1

1

CQRS(Command Query Responsibility Segregation)解决了这个问题。你有“真正的”模型,域模型,所有的业务规则等等,还有一个“query-ony”模型,它基本上是一个简单的 poco(可以由 Views 直接使用),它将由 a 返回专门查询的存储库。

持久性模型(EF 实体)仅用于与数据库“对话”,存储库始终返回或处理域/应用程序对象。基本上,您必须将 EF 实体映射到域实体(保存时反之亦然)。通过这种方式,您将拥有不同的模型,每个模型都有自己的用途。

于 2012-07-02T08:24:33.513 回答