存储库模式中的共享存储库

时间:2011-01-07 16:54:42

标签: c# repository-pattern

存储库依赖?假设我有一个类似于以下内容的域名:

public class User
{
    public int UserId { get; set; }
    public Lazy<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public User Poster { get; set; }
}

有帖子的用户。

如何设置我的存储库,以便每个user都会返回Post的列表,而对于每个post,我会得到Poster

我有2个存储库:

public class UserRepository : IUserRepository
{
    public IQueryable<User> GetUsers();
}

public class PostRepository : IPostRepository
{
    public IQueryable<Post> GetPosts();
}

我尝试从1个存储库调用另一个存储库,但它最终导致崩溃,因为存在循环依赖关系。

我正在使用存储库模式的POCO方法和实体框架。

2 个答案:

答案 0 :(得分:1)

  

我有2个存储库:

public class UserRepository : IUserRepository
{
    public IQueryable<User> GetUsers();
}

public class PostRepository : IPostRepository
{
    public IQueryable<Post> GetPosts();
}

这可能会成为问题。

您可能不想简单地GetUsers。正如您所说,您希望子实体加载了聚合或顶级实体。

根据使用环境 - 您的直接目的是什么 - 将会发生变化User。您可能最终会使用GetUsers,“GetUsersWithPostsGetUsersForImportantReportGetUsersForAttendingAnIceCreamSocial等等方法,但这些方法令人作呕。

缺少的是角色的概念。

您检索用户的角色是什么?这里明确的模型。

从聚合的基本界面开始。基本属性可以在这里

public interface IUser {
  public Guid UserId { get; set; }
  public string UserName { get; set; }
  public IEnumerable<Posts> { get; set; }
}

添加界面以支持您将使用该用户的角色。

public interface IAddPostsToUser : IUser {
  public void AddPost(Post post);
}

您的存储库可以这样定义:

public interface IUserRepository {
  User Get<TRole>(Guid userId) where TRole : IUser;
}

现在,使用该角色定义提取策略;

public interface IFetchingStrategy<TRole> {
  TRole Fetch(Guid id, IRepository<TRole> role)
}

您的存储库将通过注入或服务位置获取提取策略并调用提取。您可以传递存储库以提供FetchingStrategy查询的机制,或让FetchingStrategy注入或查找需要查询的服务。

当然,您的查询方式取决于您的ORM。

但这种建模方式有助于避免在不同情况下加载实体图形时出现的许多问题。

答案 1 :(得分:-1)

恕我直言,这属于服务层,而不是存储库层。存储库只包装数据库。

public IQueryable<UserData> GetUsersWithPosts()
{
    return from u in UserRepository.GetUsers()
           select new UserData 
           {
               Id = u.Id,
               Name = u.Name
               Posts = from p in u.Posts
                       select new PostData
                       {
                           Id = u.Id,
                           Title = p.Title
                       }
           };

...根据需要添加安全问题,聚合等。