“安全”可查询服务层设计?

时间:2015-06-11 09:17:48

标签: c# entity-framework service-layer

想象一下,您正在使用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和服务层也相当陌生,所以很自然地在寻找“最佳实践”和“已知陷阱”,同时也希望保持我的代码清洁。

1 个答案:

答案 0 :(得分:2)

听起来您正在将业务层逻辑泄漏到表示层中。

如评论中所述,确定应由表示层显示的确切数据集实际上是业务逻辑。 您的UI上可能有字段,使用户能够选择要显示的特定年龄范围,这是完全有效的,但表示层应负责将这些值推送到服务层并提供它返回的数据以友好/预期的方式进入实际用户界面。

基于这些值的数据的实际搜索/调整应该在服务层/业务层内完成。