I'm trying to roll out a strategy pattern with entity framework and the repository pattern using a simple example such as User
and Post
in which a user has many posts.
From this answer here, I have the following domain:
public interface IUser {
public Guid UserId { get; set; }
public string UserName { get; set; }
public开发者_如何学编程 IEnumerable<Post> Posts { get; set; }
}
Add interfaces to support the roles in which you will use the user.
public interface IAddPostsToUser : IUser {
public void AddPost(Post post);
}
Now my repository looks like this:
public interface IUserRepository {
User Get<TRole>(Guid userId) where TRole : IUser;
}
Strategy (Where I'm stuck). What do I do with this code? Can I have an example of how to implement this, where do I put this?
public interface IFetchingStrategy<TRole> {
TRole Fetch(Guid id, IRepository<TRole> role)
}
My basic problem was what was asked in this question. I'd like to be able to get Users without posts and users with posts using the strategy pattern.
If we talk about strategy pattern then IFetchingStrategy must be passed to IUserRepository so I think you should modify Get operation:
public interface IUserRepository
{
User Get<TRole>(Guid userId, IFetchingStrategy<TRole> strategy) where TRole : IUser;
}
But I'm not sure how to implement such interfaces with EF.
If we return to your former question, it can also be accomplished this way:
public interface IUserRepository
{
User Get(Guid userId, IEnumerable<Expression<Func<User,object>>> eagerLoading);
}
public class UserRepository : IUserRepository
{
public User Get(Guid userId, IEnumerable<Expression<Func<User,object>>> eagerLoading)
{
ObjectQuery<User> query = GetBaseQuery(); // get query somehow, for example from ObjectSet<User>
if (eagerLoading != null)
{
foreach(var expression in eagerLoading)
{
// This is not supported out of the box. You need this:
// http://msmvps.com/blogs/matthieu/archive/2008/06/06/entity-framework-include-with-func-next.aspx
query = query.Include(expression);
}
}
return query.SingleOrDefault(u => u.Id == userId);
}
}
You will use the method this way:
User userWithoutPosts = repository.Get(guid, null);
User userWithPosts = repository.Get(guid, new List<Expression<Func<User,object>>>
{
u => u.Posts
});
But I guess that this implementation works only for first level of navigation properties.
An answer in the following post uses strategy pattern to manipulate a query.
https://codereview.stackexchange.com/questions/3560/is-there-a-better-way-to-do-dynamic-filtering-and-sorting-with-entity-framework
精彩评论