【问题标题】:Dynamic Or Clause Linq动态或子句 Linq
【发布时间】:2014-07-31 05:10:01
【问题描述】:

今天我们目前有这样的声明:

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);
}

问题是我们的用户可以拥有多个角色。如果用户既是顾问又是医师,我们希望系统撤回所有顾问 ID == UserID 或 PhysicianID == 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);
}

【问题讨论】:

标签: c# linq where-clause conditional-statements dynamic-linq


【解决方案1】:

您可以逐步构建谓词。

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);

【讨论】:

  • 感谢@dcastro,这帮助我找到了albahari.com/nutshell/predicatebuilder.aspx
  • 我对变量x 的来源感到困惑?似乎谓词构建将采用单独的方法,但我很难找出适当的方法签名。
  • @TheMuffinMan 哎呀,x 应该是 p。现已修复
  • @dcastro 这更有意义。谢谢!
【解决方案2】:

这行得通吗?

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

【讨论】:

    【解决方案3】:

    以防万一其他人正在寻找我找到的不同解决方案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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多