Repository ASP.NET MVC 中的架构抽象问题

发布于 2024-08-18 06:33:40 字数 696 浏览 3 评论 0原文

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

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 搜索的所有这些(和未来)方法,是否可以只有一个方法?

I'm working with MVC ASP.NET 3.5 SP1 on VS2008.
I'm looking for a way to abstract this three methods I have in my Users repository.

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)));
}

My DB.edmx contains the models

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

Is it possible to have only ONE method for all of these (and future) methods based upon model.id search?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

_蜘蛛 2024-08-25 06:33:40
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);

我的语法可能不太正确,但你明白了。

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

Now use it:

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

You can also use 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);

I may not have the syntax quite correct, but you get the idea.

吝吻 2024-08-25 06:33:40

如果所有关联的实体(日志、产品和照片)都将通过公共属性(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 并从一个方法向其传递日志、照片或产品实体。它不是很优雅,但适用于这种特定情况。

If all the associated entities (Log, Product and Photo) will be searched by a common property (id INT) then maybe you could try something like this...

First, create an interface:

public interface IUserAssociation
{
    int id { get; }
}

Then each of the three classes would implement this interface like so:

public partial class Product : IUserAssociation
{
}

The the GetUser method would look like so:

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();
    }
}

Then you should be able to call GetUser and pass it a Log, Photo or Product entity from one method. It is not very elegant but would work for this specific situation.

一页 2024-08-25 06:33:40

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

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

如果您的所有实体都派生自

public interface IEntity { public int Id { get; } }

then 方法,

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 架构的想法,如果实体1.Id ==实体2.Id(对于持久性实体)然后等于(实体1,实体2) - 我们可以使用getlist(x).Contains(样本)。

I like Craig's solution better but I'd suggest this:

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

Which will be possible if all your entities derive from

public interface IEntity { public int Id { get; } }

Then method will be like

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();
}

Also if we take idea of S#arp Architecture that if entity1.Id == entity2.Id (for persistent entities) then Equals(entity1, entity2) - we can use getlist(x).Contains(sample).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文