如何在使用泛型类时通过PK查询EF?

时间:2011-01-07 23:12:28

标签: c# entity-framework

我正在尝试实现一个与通用存储库交互的泛型类,除了我必须处理从存储库中获取对象之外,一切都很好。

我将在泛型类中有一个虚拟方法,它将接收int并且我想使用int来形成对通过其主键获取对象的存储库的查询。我有一种感觉,我需要使用EF中的EntityKey属性,但不太确定如何。

无论如何,这是我在代码中尝试做的事情,我希望有人会就如何实现我想要的事情提出建议:

public virtual T Get(int PrimaryKey) {
    this.Repository.Select(
        t =>
            (t.PRIMARYKEY == PrimaryKey)).Single();
}

我想用更专业的类来扩展这个类,但是由于大多数类只通过查询PK来获取它们的对象,因此我可以使用基本方法来实现它。

提前感谢任何建议!

更新

所以,这里是我得到反思的地方,我怀疑它是正确的方式,但它有点工作......我得到一个NotSupportedException消息 LINQ to Entities不识别方法'System.Object GetValue(System.Object,System.Object [])'方法,并且此方法无法转换为商店表达式。。虽然我理解它的内容以及为什么会这样说,但是当我的代码看起来像这样时,我不确定如何克服它:

private readonly string TEntityName = typeof(T).Name;

public virtual T Get(
    int PrimaryKey) {
    return this.Repository.Select(
        t =>
            (((int)t.GetType().GetProperties().Single(
                p =>
                    (p.Name == (this.TEntityName + "Id"))).GetValue(t, null)) == PrimaryKey)).Single();
}

希望有人知道如何使用反射,不像我,可以指出我正确的方向。谢谢!

2 个答案:

答案 0 :(得分:1)

使用EF通过PK检索实体需要表达式/谓词,如下所示:

Expression<Func<Order,bool>> predicate = x => x.OrderId == 1;
return ctx.Orders.Single(predicate);

没有简单的方法(缺少反射或表达式树创建)能够动态创建此谓词。

您可以做的是接受谓词作为参数:

public virtual T Get(Expression<Func<T,bool>> predicate) {
    this.Repository.Select(predicate).Single();
}

还要确保在T上放置一些通用约束(在类/方法级别)。

答案 1 :(得分:0)

http://msdn.microsoft.com/en-us/library/bb738961.aspx是要走的路。然后使用http://msdn.microsoft.com/en-us/library/bb738607.aspx,花一些时间在调试器中,你的misson就完成了。