【发布时间】:2015-08-26 21:35:00
【问题描述】:
假设您使用 EntityFramework 作为您的 ORM,所有这些都包含在一个单独的 DAL 类库中。
您在另一个“通用”类库中有以下 POCO 对象,它在您的 DAL、SL 和表示层之间很好地共享:
public class User
{
public int Id { get; set;}
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
}
然后您在 SL 中实现以下内容:
public interface IUserService
{
User GetById(int u);
List<User> GetByLastName(string s);
}
public class UserService : IUserService
{
private MyContext _myContext;
public UserService(MyContext myContext = null)
{
_myContext = myContext ?? new MyContext();
}
public User GetById(int userId)
{
return _myContext.Users.FirstOrDefault(u=>u.Id == userId);
}
public List<User> GetByLastName(string lastName)
{
return _myContext.Users.Where(u=>u.LastName == lastName).ToList();
}
}
所有的作品都很好。
.
但随后您需要向服务添加一个新方法来处理不同的查询(例如,属于某个年龄段的用户)。
然后是另一个。
还有一个...
.
没多久,你开始思考
如果你能提供任何你能想到的查询,那不是很好吗 通过到服务层,它会得到相关的数据和 为您返回它,而不必显式定义每个可能 查询作为一种独特的方法,与 SL 已经是相同的方式 用 DAL 做什么?
所以问题是:
这是否可以在 SL 中安全地实现,同时仍然 保持松耦合? .
我读过使用 IQueryable 会导致灾难,例如:
q.Where(x=>{Console.WriteLine("fail");return true;});
但我对使用 ORM 和服务层也很陌生,所以自然会寻找“最佳实践”和“已知陷阱”,同时也希望保持我的代码干净。
【问题讨论】:
-
阅读:cuttingedge.it/blogs/steven/pivot/entry.php?id=95。这是一个很大的变化,但是一旦完成,添加查询(和命令)就非常容易。您需要为查询编写代码(来处理它),仅此而已。
-
如果您稍微翻转一下,您会问是否将有关如何以特定方式选择用户的业务逻辑放在表示/用户界面层中是否明智。你会怎么回答?
-
@JamesThorpe 同意业务逻辑不在 UI 层,但是,如果您只是出于显示目的选择用户,那是否仍算作业务逻辑,而不是表示逻辑?跨度>
-
按年龄范围搜索用户对我来说是业务逻辑,是的。在两个月内,当您在其他地方需要相同的逻辑时,您只需将其移至业务层即可:)
-
@JamesThorpe 我想如果你考虑一下,这很有道理:)
标签: c# entity-framework service-layer