2

我有许多结构相同但命名约定不同的实体对象,例如 Products1、Products2、Products3(这是遗留数据库模式的一部分,我对此无能为力)。

就 CLR 而言,这些类具有不同的类型,不幸的是,由于设计代码是自动生成的,我无法在这些人身上添加一个接口来显示共性。所以,我的问题是:有没有办法按名称检索实体对象?

在对这些对象应用基本相同的逻辑时,我基本上想避免切换/案例业务。

4

3 回答 3

2

您可以构建一个表达式树来查询有问题的一个或多个对象:

public T GetSingleObject<T>(int someValue) {
    MyEntities db = new MyEntities();
    var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

    var param = Expression.Parameter(typeof(T));

    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.Equal(
            Expression.Property(param, "WhateverPropertyYourComparing"),
            Expression.Constant(someValue)),
        param);

    return result.SingleOrDefault(lambda);
}

或者如果你想要一个对象的集合

public IEnumerable<T> GetResultCollection<T>(int someValue) {
    MyEntities db = new MyEntities();
    var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

    var param = Expression.Parameter(typeof(T));

    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.Equal(
            Expression.Property(param, "WhateverPropertyYourComparing"),
            Expression.Constant(someValue)),
        param);

    return result.Where(lambda);
}

当然,如果您想要的查询很长,这可能会失控,您应该考虑使用部分类添加必要的接口,正如 Justin Morgan 建议的那样。

请注意,此方法假定您的 ObjectSet 集合与您的对象同名,加上一个“s”,即“Invoice”到“Invoices”。如果不是这种情况,即“Person”到“People”,那么您可以使用 System.Data.Entity.Design.PluralizationServices.PluralizationService 来获取正确的名称

于 2011-02-19T20:22:38.620 回答
1

由于 EF4 类是部分类,因此您实际上可以扩展它们并使它们实现您选择的接口,所有这些都在一个单独的文件中。

另一种方法是使用dynamic- 只需根据实体的类型实例化实体。

dynamic myEntity= Activator.CreateInstance(Type.GetType("EntityTypeHere")));
myEntity.CommonProperty = "Foo";

这里最大的缺点是你在编译时失去了所有类型安全——任何你只会在运行时发现的问题,而且它比静态类型的方法慢。

于 2011-02-19T02:26:31.743 回答
0

根据我们讨论的类的数量以及您需要的灵活性,接口可能不是不可能的。我使用泛型做了类似的事情:

//WARNING: Partially-remembered code ahead...
interface IDuckEntity
{
    int FeatherCount { get; set; }
}

public partial class Products1 : IDuckEntity { }
public partial class Products2 : IDuckEntity { }
public partial class Products3 : IDuckEntity { }

//in some other class:
void DoStuff<T>(T entity) where T : EntityObject, IDuckEntity
{
     entity.FeatherCount = 500;
}

因此,基本上,您设置了一个单独的文件,在其中放置接口和一些小的部分类声明。然后,您将可以访问通用结构。我不知道你的确切情况是什么,但这对我来说就像一个魅力。

于 2011-02-19T02:12:38.320 回答