想象一下,您正在使用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和服务层也相当陌生,所以很自然地在寻找“最佳实践”和“已知陷阱”,同时也希望保持我的代码清洁。
答案 0 :(得分:2)
听起来您正在将业务层逻辑泄漏到表示层中。
如评论中所述,确定应由表示层显示的确切数据集实际上是业务逻辑。 您的UI上可能有字段,使用户能够选择要显示的特定年龄范围,这是完全有效的,但表示层应负责将这些值推送到服务层并提供它返回的数据以友好/预期的方式进入实际用户界面。
基于这些值的数据的实际搜索/调整应该在服务层/业务层内完成。