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层等"。

     

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

  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/darrenji/p/4078175.html
Copyright © 2011-2022 走看看