zoukankan      html  css  js  c++  java
  • 在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建

    通常,在同一个页面上实现增删改查,会通过弹出框实现异步的添加和修改,这很好。但有些时候,是不希望在页面上弹出框的,我们可能会想到Knockoutjs,它能以MVVM模式实现同一个页面上的增删改查,再辅以knockout.validation.js,还可以对Model进行验证。但knockout.validation.jsASP.NET MVC本身的验证没有做到无缝对接,不能形成一个从客户端到服务端连贯、统一的验证解决方案。关于在ASP.NET MVC中使用Knockoutjsknockout.validation.js,不知道各位朋友有没有好的案例?


    于是,蓦然回首,jQuery在灯火阑珊处无比坚定地说:我已经和ASP.NET MVC联袂好久了,什么客户端验证、服务端验证,那都不是事!大致想做成这样:

     

    显示的时候,只出现数据列表和搜索条件:
    15

     

    当点击"添加"按钮,在列表和搜索区域上方出现添加区域:
    16

     

    当点击"修改"按钮,在列表和搜索区域上方出现修改区域:
    17


    Repository的搭建

    在Models文件夹下创建一个简单的领域模型。

    namespace MvcApplication3.Models
    
    {
    
        public class Product
    
        {
    
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public string Category { get; set; }
    
            public decimal Price { get; set; }  
    
        }
    
    }

     

    通过EF Code First创建数据库初始数据。首先有一个派生于DbContext的EF上下文。

    using System.Data.Entity;
    
    namespace MvcApplication3.Models
    
    {
    
        public class ProductContext : DbContext
    
        {
    
            public ProductContext() : base("conn")
    
            {
    
                Database.SetInitializer(new ProductInitializer());
    
            }
    
            public DbSet<Product> Products { get; set; }
    
        }
    
    }
    

     

    数据库数据的初始化工作是在ProductInitializer类中完成的。

    using System.Data.Entity;
    
    namespace MvcApplication3.Models
    
    {
    
        public class ProductInitializer : DropCreateDatabaseIfModelChanges<ProductContext>
    
        {
    
            protected override void Seed(ProductContext context)
    
            {
    
                context.Products.Add(new Product() {Name = "秋意真浓", Price = 85M, Category = "散文"});
    
                context.Products.Add(new Product() {Name = "冬日恋歌", Price = 95M, Category = "小说" });
    
                context.Products.Add(new Product() { Name = "春暖花开", Price = 105M, Category = "散文" });
    
            }
    
        }
    
    }
    

     

    在Web.config中需要配置一下有关EF的连接字符串。

      <connectionStrings>
    
        ......
    
      <add name="conn" connectionString="Data Source=.;User=用户名;Password=密码;Initial Catalog=ProductStore;Integrated Security=True" providerName="System.Data.SqlClient" />
    
      </connectionStrings>

     

    仓储层首先需要一个接口。

    using System.Collections.Generic;
    
    namespace MvcApplication3.Models
    
    {
    
        public interface IProductRepository
    
        {
    
            IEnumerable<Product> GetAll(); //获取所有
    
            IEnumerable<Product> LoadProductPageData(ProductParam p, out int total);//获取分页数据
    
            Product GetById(int id); //根据id获取,通常显示更新页面时使用
    
            Product Add(Product item);//添加
    
            Product Update(Product item);//更新
    
            bool Delete(int id);//删除
    
            int DeleteBatch(string[] ids);//批量删除
    
        }
    
    } 
    

     

    仓储接口的实现通过EF上下文。

    using System;
    
    using System.Collections.Generic;
    
    using System.Data;
    
    using System.Linq;
    
    namespace MvcApplication3.Models
    
    {
    
        public class ProductRepository : IProductRepository
    
        {
    
            private ProductContext db = new ProductContext();
    
            /// <summary>
    
            /// 获取所有
    
            /// </summary>
    
            /// <returns></returns>
    
            public System.Collections.Generic.IEnumerable<Product> GetAll()
    
            {
    
                return db.Products;
    
            }
    
            /// <summary>
    
            /// 获取分页数据
    
            /// </summary>
    
            /// <param name="para">查询参数,包括:PageInde, PageSize,与Product有关的Name,Category</param>
    
            /// <param name="total">查询条件过滤之后的记录总数</param>
    
            /// <returns></returns>
    
            public IEnumerable<Product> LoadProductPageData(ProductParam para, out int total)
    
            {
    
                var products = db.Products.AsEnumerable();
    
                if (!string.IsNullOrEmpty(para.Name))
    
                {
    
                    products = products.Where(p => p.Name.Contains(para.Name));
    
                }
    
                if (!string.IsNullOrEmpty(para.Category))
    
                {
    
                    products = products.Where(p => p.Category.Contains(para.Category));
    
                }
    
                total = products.Count();
    
                IEnumerable<Product> result = products
    
                    .OrderByDescending(x => x.Id)
    
                    .Skip(para.PageSize * (para.PageIndex - 1))
    
                    .Take(para.PageSize);
    
                return result;
    
            }
    
            /// <summary>
    
            /// 根据Id获取
    
            /// </summary>
    
            /// <param name="id"></param>
    
            /// <returns></returns>
    
            public Product GetById(int id)
    
            {
    
                return db.Products.Find(id);
    
            }
    
            /// <summary>
    
            /// 添加
    
            /// </summary>
    
            /// <param name="item"></param>
    
            /// <returns></returns>
    
            public Product Add(Product item)
    
            {
    
                db.Products.Add(item);
    
                db.SaveChanges();
    
                return item;
    
            }
    
            /// <summary>
    
            /// 更新
    
            /// </summary>
    
            /// <param name="item"></param>
    
            /// <returns></returns>
    
            public Product Update(Product item)
    
            {
    
                try
    
                {
    
                    if (item == null)
    
                    {
    
                        throw new ArgumentException("Product不能为null");
    
                    }
    
                    var entry = db.Entry(item);
    
                    if (entry.State == EntityState.Detached)
    
                    {
    
                        var set = db.Set<Product>();
    
                        Product attachedProduct = set.Local.SingleOrDefault(p => p.Id == item.Id);
    
                        //如果已经被上下文追踪
    
                        if (attachedProduct != null)
    
                        {
    
                            var attachedEntry = db.Entry(attachedProduct);
    
                            attachedEntry.CurrentValues.SetValues(item);
    
                        }
    
                        else //如果不在当前上下文追踪
    
                        {
    
                            entry.State = EntityState.Modified;
    
                        }
    
                    }
    
                    db.SaveChanges();
    
                    return item;
    
                }
    
                catch (Exception)
    
                {              
    
                    throw;
    
                }
    
            }
    
            /// <summary>
    
            /// 删除
    
            /// </summary>
    
            /// <param name="id"></param>
    
            /// <returns></returns>
    
            public bool Delete(int id)
    
            {
    
                Product product = db.Products.Find(id);
    
                db.Products.Remove(product);
    
                if (db.SaveChanges() > 0)
    
                {
    
                    return true;
    
                }
    
                else
    
                {
    
                    return false;
    
                }
    
            }
    
            /// <summary>
    
            /// 批量删除
    
            /// </summary>
    
            /// <param name="ids"></param>
    
            /// <returns></returns>
    
            public int DeleteBatch(string[] ids)
    
            {
    
                foreach (string id in ids)
    
                {
    
                    Delete(int.Parse(id));
    
                }
    
                return -1;
    
            }
    
            
    
        }
    
    }
    

    以上,需要特别说明的是Update方法,为类避免在更新的时候报类似"ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象"错,因为,在EF上上下文中是不允许存在2个具有相同键的实体的。在更新的时候,我们需要判断需要被更新的实体是否已经被当前上下文追踪。


    当然,在三层架构中,我们可以通过CallContext线程槽获取到当前线程内的唯一EF上下文实例。详细做法请参考"MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等"。

     

    下一篇进入增删改查的界面设计。

  • 相关阅读:
    SCAU 12新生赛 H 拥挤的华农校巴
    C#实现让CPU占用率曲线听你的指挥 可指定运行核心
    追MM与设计模式的有趣见解
    FTP操作类
    怎么知道页面被放大缩小了
    SerialPort同步和异步数据读取
    Java Web 应用程序转换为 ASP.NET
    ASP.NET中进行消息处理(MSMQ)
    解压缩文件类
    怎样成为优秀的软件模型设计者?
  • 原文地址:https://www.cnblogs.com/darrenji/p/4078175.html
Copyright © 2011-2022 走看看