我刚刚发现了扩展方法,我非常喜欢它们,所以我很害怕它们的用途......
我有一个3层的Asp Net应用程序。我的DAL基于实体框架,我的UI是aspx页面,我的业务逻辑曾经是LINQ实体查询的常见类,如下所示:
public List<Site> GetAll()
{
return db.Sites.Include(s=> s.City).ToList();
}
你需要像这样实例化和使用:
CSite objsite = new CSite();
List<Site> sites = objsite.GetAll();
然后我发现Iqueryable,所以这样我就可以“重复使用”我的查询:
public ObjectQuery<Site> GetAll()
{
return db.Sites.Include(s=> s.City);
}
public IQueryable<Site> Filter(IQueryable<Site> query, string filterWord)
{
return (from s in query
s.Name.Contains(word)
select s);
}
List<Site> sites = objsite.Filter(objsite.GetAll(),"filter word").ToList();
Filter()方法只是在GetAll()iqueryable上应用了where子句,这很棒,直到我发现了扩展方法,所以我可以像这样处理它:
public static IQueryable<Site> Filter(this IQueryable<Site> query, string word)
{
return (from s in query
s.Name.Contains(word)
select s);
}
这甚至更好,因为现在我对我的查询进行了智能感知:
List<Site> sites = objsite.GetAll().Filter("filter word").ToList();
现在,这是我害怕的部分,因为有三件事:
你认为这是一个很好的n层应用程序吗?这是一个好的设计模式还是只是一个懒惰的解决方案?
鉴于扩展方法的要求是静态类下的静态方法,我的业务层将是静态的,这是一个好方法吗?我应该将非扩展方法放在同一个静态类下吗? (例如GetAll()或AddNew())
Asp Net应用程序拥有所有这些静态内容是否合适?
非常感谢你们!
答案 0 :(得分:2)
在IQueryable
之上使用自定义扩展方法是很常见的。我认为这是重用查询部分的好方法。使用扩展方法时应谨慎使用。扩展方法只是围绕静态方法的一种语法糖。我的朋友有一个关于他最近发现扩展方法并开始使用代码的同事的好故事:
var order = 1.GetOrder(); // Extension on integer - this is really bad example
您的示例中的问题是静态业务层。业务层必须以某种方式接收上下文,并且必须按请求处理上下文。请求中的Sharing context或整个应用程序的单个上下文是遇到严重问题的最佳方法。因此,除非您将上下文传递给每个方法,否则您还必须为每个请求创建业务类。
但是你仍然应该在IQueryalbe
上使用扩展程序。您可能会发现您的业务类只是context.Query
的包装器,在这种情况下,它是不需要的附加层。
另外请注意,这一切都适用于分层体系结构,但如果你的n层意味着真正的物理分离(每个层在一个单独的服务器上),那么它是一个不同的故事,因为你需要的东西可以让你创建一个linq查询在一个层上并在另一个层上执行它(在另一个服务器上,因此查询和结果必须通过网络传输) - 一个这样的工具是WCF数据服务。