我試圖使用實體框架CommandTree攔截器通過DbContext爲每個查詢添加一個過濾器。爲了簡單起見,我有兩個表,一個名爲「User」,兩列(「UserId」和「EmailAddress」),另一個名爲「TenantUser」,兩列(「UserId」和「TenantId」) 。在實體框架攔截器中添加內部連接到DbScanExpression
每次有用戶表的DbScan時,我想根據TenantId列對TenantUser表進行內部聯接並進行篩選。
有一個名爲EntityFramework.Filters的項目,它沿着這些線做了一些事情,但不支持「複雜連接」,這似乎是我正在嘗試做的。
繼a demo from TechEd 2014後,我創建了一個攔截器,它使用訪問器並使用下面的方法用DbJoinExpression替換DbScanExpressions。一旦我得到這個工作,我打算將它包裝在一個DbFilterExpression中,以將TenantId列與已知ID進行比較。
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();
然而,這會導致以下錯誤:
No property with the name 'EmailAddress' is declared by the type 'Transient.rowtype[(l,CodeFirstDatabaseSchema.User(Nullable=True,DefaultValue=)),(r,CodeFirstDatabaseSchema.User(Nullable=True,DefaultValue=))]'.
我是不是正確構建了DbJoinExpression?還是我錯過了別的?
這正是我所需要的。非常感謝! – 2015-04-09 16:22:16
我的回答很可能對你來說太晚了,對不起,但對未來有些人可能會使用它。 – mr100 2015-04-09 16:23:35
有沒有辦法將正則表達式傳遞給訪問者以使這些掃描的寫入更容易? – AndrewP 2016-01-04 09:40:35