我正在尝试在 EF4 中实现加密列,并使用 CTP5 功能来允许简单地使用 POCO 来查询数据库。抱歉,这是很多话,但我希望下面的内容足以解释需求和问题!
那么,一些背景知识以及我迄今为止的进展:
目的是,如果您在不使用我们的 DAL 的情况下查询表,那么数据就是垃圾,但我不希望开发人员担心数据是否/何时/如何加密。
为简单起见,现阶段我假设任何字符串列都将被加密。
现在,我已经成功实现了使用 Objectmaterialized 事件返回数据以及使用 SavingChanges 事件提交数据的功能。
因此给出以下课程:
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 物化中包含清晰的数据。
var things = from t in myDbContext.Things
select t;
其中 myDbContext.Things 是DbSet<Thing>
同样,传递一个实例Thing
to Things.Add()
(名称和/或其他字符串值中包含清晰的字符串数据)
然后打电话myDbContext.SaveChanges()
在字符串到达数据存储之前对其进行加密。
现在,我遇到的问题是在这个查询中:
var things = from t in myDbContext.Things
where t.Name == "Hairbrush"
select t;
这会导致将未加密的值与数据库中的加密值进行比较。显然我不想从数据库中获取所有记录,具体化它们,然后根据任何提供的Where子句过滤结果......所以我需要做的是:拦截该查询并通过加密Where子句中的任何字符串来重写它。所以我看过:
- 编写一个查询提供程序,但这似乎不是正确的解决方案......(is it?)
- 为 DbSet 编写我自己的 IQueryable 包装器,它将捕获表达式,使用表达式树访问者运行它,然后将新表达式转发到 DbSet...
这两种尝试都让我有些迷失!我认为我更喜欢第二种解决方案,因为它感觉更简洁,并且将来对其他开发人员来说可能更清晰。但我很乐意与其中一个或另一个一起去better选项!!
我遇到的主要问题是 LINQ 表达式何时/如何应用于对象...我想我自己对表达式在 IQueryable 对象中执行的位置有点困惑,因此我不确定哪种方法我需要在我的包装器中实现,然后抓取和操作传入的表达式......
我确信我在这里遗漏了一些相当明显的东西,我正在等待那个灵光乍现的时刻……但它没有来!
任何帮助将非常感激!