问题
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.
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/4706884/fetching-strategy-example-in-repository-pattern-with-pure-poco-entity-framework