【问题标题】:Entity framework builds views and controllers... which i have to re-work into my repositories实体框架构建视图和控制器......我必须在我的存储库中重新工作
【发布时间】:2013-12-10 00:16:24
【问题描述】:

实体框架是否有一些自动化的功能,这意味着我不必重新编写 crud 控制器和视图来使用我的存储库和统一框架注入:(?

它在控制器中显式引用实体框架数据库上下文...然后在控制器本身内部执行实际数据操作...

例如,这会在我的控制器中结束:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include="ProductID,Title")] Product product)
    {
        if (ModelState.IsValid)
        {
            db.Products.Add(product);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(product);
    }

当 .Add 和 .SaveChanges 确实需要在我的存储库中时...

我不想每次创建这些东西时都编写 50 个 CRUD 操作或复制和粘贴视图和控制器...有没有自动化的方法

大概是这样的:

namespace WebApplication.Domain.Abstract
{
    public interface IProductRepository
    {
        IQueryable<Product> Products { get; }
        Product Create(Product product);
        ... yada yada crud operations
    }
}

public class EFProductRepository : IProductRepository
{
    private EFDbContext context = new EFDbContext();

    public IQueryable<Product> Products
    {
        get { return context.Products; }
    }

//... implements all the CRUD operations that entity framework ends up placing inside the controller
}

【问题讨论】:

  • 发布一些代码将非常有益。很难理解你在这里问什么。
  • 你很快 :) 实际上我在完成之前不小心提交了问题 ;) soz... 现在完成
  • 您想自动化什么?如果是代码生成,那么 T4 msdn.microsoft.com/en-us/library/bb126445.aspx 可能就是您要找的。​​span>
  • 啊,你这个美女。正是我需要的.. 我已经将实体框架自动创建转换为我的存储库表单,但是如果我将来可以自动化这些东西,那就太酷了!继续写同样的废话真是太烦人了。

标签: c# entity-framework visual-studio-2013


【解决方案1】:

因为根据 cmets 这就是解决问题的方法:

Visual Studio 为基于模板的代码生成提供了一种内置方式。它被称为 T4,您可以阅读更多关于它的信息here。

【讨论】:

    【解决方案2】:

    通用的Repository&lt;TPoco&gt; 是这里的通用方法。

    即为每个 POCO 重复使用 1 个存储库。

    它也常与工作单元模式一起使用,将更新组合成一个逻辑工作单元。

    这是一个基本的演示来说明这一点。 但理想情况下,IRepository 在核心层中声明 和一个数据访问层实现 Repositiry:IRepository 以保持 ef 引用 在核心域层之外。 (这是另一个需要研究的重要相关代码架构问题) 这个演示太短了IRepository&lt;t&gt;

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace repofT
    {
    class Program
    {
        static void Main(string[] args)
        {
            // Kick Start Repository of T demo
            // There are advance models combining context creation / unit of work and repository.
            // The concept of Inversion of Control / Dependency injection should be inestigated
            // for the people new to IOC
            // SIMPLIFIED Unit of Work and Respository of T sample
            var ctx = new MyContext();
            var uow = new UnitOfWork(ctx);
            var rep = new Repository<MyPoco>(ctx);
    
            addTest(rep, uow);
    
            var poco1 = FindTest(rep);
    
            ChangeTest(poco1, rep, uow);
    
            Console.ReadKey();
        }
    
        private static void ChangeTest(MyPoco poco1, Repository<MyPoco> rep, UnitOfWork uow)
        {
            poco1.Content = "Test - was changed";
            rep.Change(poco1);
            uow.Commit();
            DumpTest(rep);
        }
    
        private static MyPoco FindTest(Repository<MyPoco> rep)
        {
            var poco1 = rep.Find(1);
            Console.WriteLine(poco1.Id + " : " + poco1.Content);
            return poco1;
        }
    
        private static void addTest(Repository<MyPoco> rep, UnitOfWork uow)
        {
            var mypoco = new MyPoco()
            {
                Content = "Test" + System.DateTime.Now.ToString(CultureInfo.InvariantCulture),
            };
            rep.Add(mypoco);
            uow.Commit();
    
            DumpTest(rep);
        }
    
        private static void DumpTest(Repository<MyPoco> rep)
        {
            var pocoList = rep.GetList(t => t.Content.StartsWith("Test"));
            if (pocoList != null)
            {
                foreach (var poco in pocoList)
                {
                    Console.WriteLine(poco.Id + " : " + poco.Content);
                }
            }
        }
    }
    }
    

    以及存储库/工作单元和上下文类

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity;
    using System.Linq;
    using System.Data.Entity.Validation;
    using System.Linq.Expressions;
    
    namespace repofT
    {
    /// <summary>
    /// Note to the reader. NO error handling. You should add your preferred solution.
    /// This is a stripped down sample to illustrate how Repository of T pattern works.
    ///  </summary>
    
    public class MyContext : DbContext
    {
       public DbSet<MyPoco>  MyPocos { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //fluent API....
            base.OnModelCreating(modelBuilder);
            var entity = modelBuilder.Entity<MyPoco>();
            entity.HasKey(t => t.Id)   ;
            entity.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }
    
    public class MyPoco
    {
        //virtuals for EF, especially Proxies and navigation, Use public get/set
     public virtual   int Id { get; set; }
     public virtual   string Content { get; set; }
    }
    
    public class Repository<TPoco> where TPoco : class, new()
    {
        public DbContext Context { get; private set; }
    
        public Repository(DbContext context){
            Context = context;
        }
    
        public IList<TPoco> GetList(Expression<Func<TPoco, bool>> predicate)
        {
            // Investigate returning IQueryable versus IList as you learn more.
            return GetQuery(predicate).ToList();
        }
        public IQueryable<TPoco> GetQuery(Expression<Func<TPoco, bool>> predicate)
        {
            // Investigate returning IQueryable versus IList as you learn more.
            return Context.Set<TPoco>().Where(predicate);
        }
        public TPoco Get(Expression<Func<TPoco, bool>> predicate)
        {
            return Context.Set<TPoco>().FirstOrDefault(predicate);
        }
    
        public TPoco Find(params object[] keyValues)
        {
            return Context.Set<TPoco>().Find(keyValues);
        } 
    
        public TPoco Attach(TPoco poco)
        {
            return Context.Set<TPoco>().Add(poco);
        }
        public TPoco Add(TPoco poco){
            return Context.Set<TPoco>().Add(poco);
        }
    
        public TPoco AddOrUpdate(TPoco poco){
            return Context.Set<TPoco>().Add(poco);
        }
    
        public TPoco Remote(TPoco poco){
            return Context.Set<TPoco>().Remove(poco);
        }
    
        public void Change(TPoco poco){
            Context.ChangeTracker.DetectChanges();
        }
    
        public void SetEntityState(TPoco poco, EntityState state = EntityState.Modified){
            Context.Entry(poco).State = state;
        }
    }
    
    
    public class UnitOfWork
    {
        public DbContext Context { get; protected set; }
    
        public  UnitOfWork(DbContext context){
            Context = context;
        }
         public IEnumerable<DbEntityValidationResult> GetDbValidationErrors() { return 
            Context.GetValidationErrors(); 
         }
    
        public int Commit()
        {
            try {
                var recs = Context.SaveChanges();
                return recs;
            }
           catch (DbEntityValidationException efException){
               var errors = GetDbValidationErrors(); // DO SOMETHING HERE !!!!!
               return -1;
           }
        }
    
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 2015-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-20
      相关资源
      最近更新 更多