动态或子句Linq

本文关键字:Linq 子句 动态 | 更新日期: 2023-09-27 18:07:51

现在我们有这样一个语句:

var Query = (from dp in db.Patients
            select dp);
var UserID = User.Identity.GetUserId();
if (User.IsInRole("Administrator"))
{
    Query = Query.Where(x => x.AdministratorID == UserID);
}
if (User.IsInRole("Counselor"))
{
    Query = Query.Where(x => x.CounselorID == UserID);
}
if (User.IsInRole("Physician"))
{
    Query = Query.Where(x => x.PhysicianID == UserID);
}

问题是我们的用户可以有多个角色。如果一个用户既是咨询师又是内科医生,我们希望系统回拉出所有advisorid == UserID或physicanid == UserID的患者。

如果我们不知道用户在加载页面时将扮演什么角色,如何动态地完成这一点?

当前. where子句只使用了AND语句,我们需要一个OR语句。

理想情况下会有这样的解决方案:

if (User.IsInRole("Administrator"))
{
     Query = Query.Where(x => x.AdministratorID == UserID);
}
if (User.IsInRole("Counselor"))
{
     Query = Query.WhereOr(x => x.CounselorID == UserID);
}
if (User.IsInRole("Physician"))
{
     Query = Query.WhereOr(x => x.PhysicianID == UserID);
}

动态或子句Linq

您可以增量地构建谓词。

Func<Pantient, bool> predicate = p => false;
if (User.IsInRole("Administrator"))
{
    var oldPredicate = predicate;
    predicate = p => oldPredicate(p) || p.AdministratorID == UserID;
}
if (User.IsInRole("Counselor"))
{
    var oldPredicate = predicate;
    predicate = p => oldPredicate(p) || p.CounselorID == UserID;
}

var query = db.Patients.Where(predicate);

这样行吗?

var query = Patients.Where(
    x => (User.IsInRole("Administrator") && x.AdministratorID == UserID)
      || (User.IsInRole("Counselor") && x.CounselorID == UserID)
      || (User.IsInRole("Physician") && x.PhysicianID == UserID)
    );

以防其他人正在寻找不同的解决方案,我找到了linqkit非常有用和易于使用。所以在你的例子中,解决方案是这样的:

var predicate = PredicateBuilder.New<Patients>(true);
if (User.IsInRole("Administrator"))
{
     predicate = predicate.Or(x => x.AdministratorID == UserID);
}
if (User.IsInRole("Counselor"))
{
     predicate  = predicate.Or(x => x.CounselorID == UserID);
}
if (User.IsInRole("Physician"))
{
     predicate  = predicate.Or(x => x.PhysicianID == UserID);
}
query = query.Where(predicate)