【问题标题】:How can I get Property Expression for field of a property如何获取属性字段的属性表达式
【发布时间】:2017-02-26 00:17:14
【问题描述】:

我正在使用 Entity Framework 6。我有 2 个类:

public class BookingRecord
{
    public int Id {get; set;}
    public int CustomerId {get; set;}

    [ForeignKey("CustomerId")]
    public virtual Customer Customer {get; set;}

    ......
}

public class Customer
{
    public int Id {get; set;}
    public int BusinessUnitId {get; set;}
    public int UserId {get; set;}

    ......
}

我在用户上有 BusinessUnitId 作为业务单位。

我的业务逻辑是:

如果用户是管理员,用户可以打开系统中的所有预订记录。 如果 User 是 Employee,则用户可以打开 User 上具有相同 BusinessUnitId 的所有预订记录。 如果User是RegisteredUser,则用户只能打开与该用户具有相同UserId的预订记录。 如果用户是其他角色,用户根本无法打开预订记录。

所以我为上面的业务逻辑创建了一个客户类的表达式。

    protected Expression GetUserRoleExtraConditionExpression(ParameterExpression param)
    {
        Expression expression;

        IPrincipal user = HttpContext.Current.User;

        if (user.IsInRole(Consts.Roles.Administrator))
        {
            expression = Expression.Constant(true);
        }
        else if (user.IsInRole(Consts.Roles.Employee))
        {
            int businessUnitId = UserManager.FindById(user.Identity.GetUserId()).BusinessUnitId;
            expression = Expression.Equal(
                Expression.Property(param, typeof(Customer).GetProperty("BusinessUnitId")),
                Expression.Constant(businessUnitId));
        }
        else if (user.IsInRole(Consts.Roles.RegisteredUser))
        {
            string userId = user.Identity.GetUserId();
            expression = Expression.Equal(
                Expression.Property(param, typeof(Customer).GetProperty("UserId")),
                Expression.Constant(userId));
        }
        else
        {
            expression = Expression.Constant(false);
        }
        return expression;
    }

其中 ParameterExpression 参数是 Customer 类型的参数。

对于 BookingRecord 类,我需要在 Customer 属性上应用相同的逻辑。即BookingRecord.Customer.BusinessUnitIdBookingRecord.Customer.UserId从DB中选择时必须应用上述表达式。

如何在 BookingRecord 上重复使用该方法?

换句话说,我怎样才能得到类似于Expression.Property(param, typeof(Customer).GetProperty("BusinessUnitId")) 的表达式,但接受具有BookingRecord 类型的参数并应用于BookingRecord 的CustomerField 字段? 像

Expression.Property(param,
    typeof(BookingRecord)
        .GetProperty(Customer)
        .GetProperty("BusinessUnitId"))

【问题讨论】:

  • 你为什么要这么费劲地在这里生成一个表达式?
  • Expression.Property(Expression.Property(param,...),...)
  • 谢谢pinkfloydx33,我很快就发现它就是这么简单......

标签: c# entity-framework lambda linq-to-entities linq-expressions


【解决方案1】:

感谢pinkfloydx33。 Expression.Property(Expression.Property(param,...),...) 正是我想要的。

所以我现在有方法

    protected Expression GetUserRoleExtraConditionExpression(Expression param)
    {
        Expression expression;

        IPrincipal user = HttpContext.Current.User;

        if (user.IsInRole(Consts.Roles.Administrator))
        {
            expression = Expression.Constant(true);
        }
        else if (user.IsInRole(Consts.Roles.Employee))
        {
            int businessUnitId = UserManager.FindById(user.Identity.GetUserId()).BusinessUnitId;
            expression = Expression.Equal(
                Expression.Property(param, "BusinessUnitId"),
                Expression.Constant(businessUnitId));
        }
        else if (user.IsInRole(Consts.Roles.RegisteredUser))
        {
            string userId = user.Identity.GetUserId();
            expression = Expression.Equal(
                Expression.Property(param, "UserId"),
                Expression.Constant(userId));
        }
        else
        {
            expression = Expression.Constant(false);
        }
        return expression;
    }

在 Customer 类的调用者中,我将其称为

GetUserRoleExtraConditionExpression(param);

(paramCustomer 类型ParameterExpression)

在 BookingRecord 类的调用者中,我将其称为

GetUserRoleExtraConditionExpression(Expression.Property(param, "Customer"))

paramBookingRecord 类型 ParameterExpression

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多