首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在LINQ实体查询中实现查询拦截?(c#)

如何在LINQ实体查询中实现查询拦截?(c#)
EN

Stack Overflow用户
提问于 2011-03-09 17:09:34
回答 3查看 3K关注 0票数 3

我试图在EF4中实现加密的列,并使用CTP5特性允许简单地使用POCO来查询数据库。对不起,这是很多的话,但我希望下面给出足够的解释需要和问题!

所以,关于我的背景,和我目前的进展:

这样做的意图是,如果您不使用我们的DAL查询表,那么这些数据就是垃圾数据,但我不希望开发人员担心数据是否/何时/如何加密。

为了简单起见,在这个阶段,我假设任何字符串列都将被加密。

现在,我已经成功地实现了这一点,用于使用Object物化事件返回数据,以及使用SavingChanges事件进行数据提交。

因此,考虑到以下课程:

代码语言:javascript
运行
复制
public class Thing
{

    public int ID { get; set; }
    [Required]
    public string Name { get; set; }
    public DateTime Date { get; set; }
    public string OtherString { get; set; }
}

下面的查询返回所有必需的值,POCO物化的数据在其中有明确的数据。

代码语言:javascript
运行
复制
var things = from t in myDbContext.Things
             select t;

其中myDbContext.Things是DbSet<Thing>

同样,将Thing的一个实例传递给Things.Add()

(在名称和/或OtherString值中包含清晰的字符串数据)

然后调用myDbContext.SaveChanges()在到达数据存储之前对字符串进行加密。

现在,我遇到的问题是在这个查询中:

代码语言:javascript
运行
复制
var things = from t in myDbContext.Things
             where t.Name == "Hairbrush"
             select t;

这将导致将未加密的值与DB中的加密值进行比较。显然,我不想从数据库中获取所有记录,将它们具体化,然后根据提供的Where子句过滤结果.所以我需要做的是:拦截这个查询并通过加密Where子句中的任何字符串来重写它。所以我看过:

  • 编写查询提供程序,但这似乎不是正确的解决方案.(是吗?)
  • 为DbSet编写了自己的IQueryable包装器,它将捕获表达式,使用表达式树访问器运行,然后将新表达式转发给DbSet.

这两种尝试都让我有些失败!我更喜欢我认为的第二种解决方案,因为它感觉更整洁,而且对其他开发人员来说也可能更清晰一些。但是,我很高兴加入更好的选项!!

我正在挣扎的主要事情是什么时候/如何将LINQ表达式应用于对象.我想我对表达式在IQueryable对象中的执行位置感到有点困惑,因此我不确定需要在包装器中实现哪种方法来获取和操作正在传递的表达式.

我肯定我错过了一些很明显的东西,我在等那个灯泡的时刻.但它不会来!!

任何帮助都将非常感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-24 16:35:15

我想让你知道我的最后解决方案是什么。最后,我使用了一个包装类,它实现了Where方法,但没有完全实现IQueryable。LINQ仍将对类执行(至少在我希望/需要它的范围内),并使用LINQ的表达式调用Where方法。

然后遍历这个ExpressionTree,在将新的表达式树转发到内部DbSet之前用加密的值替换字符串。然后返回结果。

它很粗糙,也有它的局限性,但对我们的特殊情况却没有问题。

谢谢,本

票数 2
EN

Stack Overflow用户

发布于 2011-03-09 17:19:32

您应该使用QueryInterceptor属性,在这里搜索,或者在google中搜索,并找到如何使用它的示例。

一段片段:

代码语言:javascript
运行
复制
[QueryInterceptor("Orders")]
public Expression<Func<Order, bool>> FilterOrders() 
{
    return o => o.Customer.Name == /* Current principal name. */;
} 

// Insures that the user accessing the customer(s) has the appropriate
// rights as defined in the QueryRules object to access the customer
// resource(s).

[QueryInterceptor ("Customers")]
public Expression<Func<Customer, bool>> FilterCustomers() 
{
  return c => c.Name == /* Current principal name. */ &&
              this.CurrentDataSource.QueryRules.Contains(
                rule => rule.Name == c.Name &&
                        rule.CustomerAllowedToQuery == true
              );
}
票数 0
EN

Stack Overflow用户

发布于 2012-07-14 11:36:02

您可以使用David Fowler的查询拦截器:

https://github.com/davidfowl/QueryInterceptor

其使用的一个例子是:

IQueryable q=.;IQueryable修饰=q.InterceptWith(新的MyInterceptor());

在MyInterceptor课堂上:

受保护的覆盖表达式VisitBinary(BinaryExpression节点){ if (node.NodeType == ExpressionType.Equal) { //更改== to !=返回Expression.NotEqual(node.Left,node.Right);}返回base.VisitBinary(节点);}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5249473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档