【问题标题】:Retrieving an Entity Object by name - LINQ to Entities, EF 4.0按名称检索实体对象 - LINQ to Entities,EF 4.0
【发布时间】:2011-02-20 04:30:12
【问题描述】:

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

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

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

【问题讨论】:

    标签: linq ef4-code-only


    【解决方案1】:

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

    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 来获取正确的名称

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        【解决方案3】:

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

        //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;
        }
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-29
          • 1970-01-01
          • 2023-04-02
          • 1970-01-01
          • 2011-06-10
          • 1970-01-01
          相关资源
          最近更新 更多