存储库ASP.NET MVC中的体系结构抽象问题

时间:2010-01-21 11:21:43

标签: asp.net-mvc architecture data-modeling repository-pattern

我在VS2008上使用MVC ASP.NET 3.5 SP1 我正在寻找一种方法来抽象我在Users存储库中的这三种方法。

public User GetUser(Log log)
{
  return db.Users.FirstOrDefault(u => u.Logs.Any(l => l.id.Equals(log.id)));
}

public User GetUser(Product product)
{
  return db.Users.FirstOrDefault(u => u.Products.Any(pr => pr.id.Equals(product.id)));
}

public User GetUser(Photo photo)
{
  return db.Users.FirstOrDefault(u => u.Photos.Any(ph => ph.id.Equals(photo.id)));
}

我的DB.edmx包含模型

User    [id, username, ...]  
Product [id, name, ...]
Photo   [id, name, ...]
Log     [id, data, ...]

基于model.id搜索的所有这些(以及将来)方法是否只能使用 ONE 方法?

3 个答案:

答案 0 :(得分:0)

public User GetUser(Expression<Func<User, bool>> restriction)
{
  return db.Users.Where(restriction).FirstOrDefault();
}

现在使用它:

var u = Repository.GetUser(u => u.Logs.Any(l => l.id.Equals(log.id)));

您还可以使用MS DynamicQuery

using System.Linq.Dynamic;

//...
public User GetUser(string propertyName, int id)
{
    var restriction = propertyName + ".Any(id = @0)";
    return db.Users.Where(restriction, id).FirstOrDefault();
}

var u = Repository.GetUser("Logs", log.id);

我可能没有正确的语法,但你明白了。

答案 1 :(得分:0)

如果所有关联的实体(日志,产品和照片)都将被公共属性(id INT)搜索,那么也许您可以尝试这样的事情......

首先,创建一个界面:

public interface IUserAssociation
{
    int id { get; }
}

然后这三个类中的每一个都会实现这样的接口:

public partial class Product : IUserAssociation
{
}

GetUser方法如下所示:

public User GetUser<T>(T entity) where T : IUserAssociation
{
    var type = typeof(T);
    if (type == typeof(Log))
    {
        return db.Users.FirstOrDefault(u => u.Logs.Any(l => l.id.Equals(entity.id)));
    }
    else if (type == typeof(Product))
    {
        return db.Users.FirstOrDefault(u => u.Products.Any(pr => pr.id.Equals(entity.id)));
    }
    else if (type == typeof(Photo))
    {
        return db.Users.FirstOrDefault(u => u.Photos.Any(ph => ph.id.Equals(entity.id)));
    }
    else
    {
        throw new ArgumentException();
    }
}

然后你应该能够调用GetUser并从一个方法传递一个Log,Photo或Product实体。它不是很优雅,但适用于这种特殊情况。

答案 2 :(得分:0)

我更喜欢克雷格的解决方案,但我建议:

Repository.GetUser(u => u.Logs, log);

如果您的所有实体都来自

,那么这将是可能的
public interface IEntity { public int Id { get; } }

然后方法就像

public User GetUser<T, Y>(Func<T, IList<Y>> getlist, Y sample)
   where T: IEntity
   where Y: IEntity
{
  return db.Users.Select(x => getlist(x).Any(y => y.Id == sample.Id)).FirstOrDefault();
}

此外,如果我们了解S#arp架构,如果entity1.Id == entity2.Id(对于持久性实体),那么Equals(entity1,entity2) - 我们可以使用getlist(x).Contains(sample)。< / p>