"safe" 可查询服务层设计?

"safe" queryable service layer design?

假设您正在使用 EntityFramework 作为您的 ORM,所有这些都包含在一个单独的 DAL class 库中。

您在另一个 "common" class 库中有以下 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();
   }
}

所有作品都很棒。
.
但是随后您需要向服务添加一个新方法来处理不同的查询(例如,属于某个年龄段的用户)。
然后是另一个。
还有一个...
.
不久,你开始思考

Wouldn't it be nice if you could provide any query you can think of through to the service layer, and it would get the relevant data and return it for you, without having to explicitly define each possibly query as a distinct method, much in the same way the SL is already doing with the DAL?

所以问题是:

Is this possible to achieve SAFELY within a SL, whilst still maintaining loose coupling? .
I've read that using IQueryable can lead to disaster with things like:

q.Where(x=>{Console.WriteLine("fail");return true;});

但我对使用 ORM 和服务层也很陌生,所以自然会寻找 "best practices" 和 "known pitfalls",同时也希望保持我的代码整洁。

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

如评论中所述,确定表示层应显示的确切数据集实际上是业务逻辑。 您的 UI 上可能有字段让用户能够 select 显示特定的年龄范围,这是完全有效的,但表示层应该负责将这些值推到服务层,并以 friendly/expected 的方式将数据 returns 提供给实际的 UI。

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