代码之家  ›  专栏  ›  技术社区  ›  Jean-Francois

实体框架4,动态查询

  •  1
  • Jean-Francois  · 技术社区  · 14 年前

    是否可以使用实体框架创建动态查询。我有18张桌子,每个都有相同的结构。如何创建一个动态查询,以便对每个表重复使用相同的查询。我想要一个创建、读取、更新、删除的通用查询。 read包含相同的“where”子句。 谢谢你的帮助。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Ladislav Mrnka    14 年前

    这里有一个简单的纯积垢场景的例子。创建包含查询共享属性的接口。在所有实体类中实现这个接口。而不是创建存储库。存储库通常被定义为泛型,但在您的情况下,我将每个方法都定义为泛型,这样您就可以对所有实体使用相同的存储库指令。

    public interface IWellKnownEntity
    {
      int Type { get; set; }
    }
    
    public class Repository
    {
      public T GetEntityByWellKnownQuery<T>() where T : IWellKnownEntity
      {
        using (var context = new MyContext())
        {
          return context.CreateObjectSet<T>().FirstOrDefault(e => e.Type == 1);
        }
      }
    
      public IEnumerable<T> GetEntitiesByCustomQuery<T>(Expression<Func<T, bool>> where)
      {
        using (var context = new MyContext())
        {
          return context.CreateObjectSet<T>().Where(where).ToList();
        }
      }
    
      public void Create<T>(T entity) where T : IWellKnownEntity
      {
        using (var context = new MyContext())
        {
          context.AddObject(entity);
          context.SaveChanges();
        }
      }
    
      public void Update<T>(T entity) where T : IWellKnownEntity
      {
        using (var context = new MyContext())
        {
          context.Attach(entity);
          context.ObjectStateManager.ChageObjecState(entity, EntityState.Modified);
          context.SaveChanges();
        }
      }
    
      public void Delete<T>(T entity) where T : IWellKnownEntity
      {
        using (var context = new MyContext())
        {
          context.Attach(entity);
          context.DeleteObject(entity);
          context.SaveChanges();
        }
      }
    }
    

    比您假设的更重要的是,您拥有实体产品和catebory,它推动了著名的接口。您只需拨打:

    var repository = new Repository();
    
    var product = repository.GetEntityByWellKnownQuery<Product>();
    product.Name = "Updated";
    repository.Update<Product>(product);
    
    var category = repository.GetEntitiesByCustomQuery<Category>(c => c.Id == 1).First();
    repository.Delete<Category>(category);
    

    您可以进一步改进示例代码。此代码不使用共享上下文,因此更适用于断开连接的场景(Web应用程序)。如果使用连接的场景(如WinForms应用程序或批处理应用程序),则可以在存储库上实现IDisposable,并在所有方法之间共享上下文。存储库上的Dispose方法将处理上下文。更新和删除方法的代码将不同,因为不需要将实体附加回上下文或设置实体状态。