Я пытаюсь использовать перехватчик Entity Framework CommandTree, чтобы добавить фильтр к каждому запросу через DbContext.
Для простоты у меня есть две таблицы, одна из которых называется "Пользователь" с двумя столбцами ( "UserId" и "EmailAddress" ), а другая называется "TenantUser" с двумя столбцами ( "UserId" и "TenantId" ).
Каждый раз, когда есть таблица DbScan для пользователя, я хочу сделать внутреннее соединение с таблицей TenantUser и фильтровать на основе столбца TenantId.
Существует проект под названием EntityFramework.Filters, который делает что-то в этом направлении, но не поддерживает "сложные объединения", что, кажется, является тем, что я пытаясь сделать.
Следуя демо от TechEd 2014, я создал перехватчик, который использует посетителя с приведенным ниже способом для замены DbScanExpressions на DbJoinExpression. Как только я получу эту работу, я планирую обернуть ее в DbFilterExpression, чтобы сравнить столбец TenantId с известным идентификатором.
public override DbExpression Visit(DbScanExpression expression)
{
var table = expression.Target.ElementType as EntityType;
if (table != null && table.Name == "User")
{
return DbExpressionBuilder.InnerJoin(expression, DbExpressionBuilder.Scan(expression.Target), (l, r) =>
DbExpressionBuilder.Equal(DbExpressionBuilder.Variable(tenantUserIdProperty.TypeUsage, "UserId"),
DbExpressionBuilder.Variable(userIdProperty.TypeUsage, "UserId")));
}
return base.Visit(expression);
}
Чтобы проверить код выше, я добавил перехватчик в dbContext и запустил следующий код:
dbContext.Users.Select(u => new { u.EmailAddress }).ToList();
Однако это приводит к следующей ошибке:
Нет свойства с именем "EmailAddress" объявляется типом "Transient.rowtype [(l, CodeFirstDatabaseSchema.User(Nullable = True, DefaultValue =)), (r, CodeFirstDatabaseSchema.User(Nullable = True, DefaultValue = ))]".
Я неправильно создаю DbJoinExpression? Или я пропущу что-то еще?