在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联袂好久了,什么客户端验证、服务端验证,那都不是事!大致想做成这样:

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

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

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

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

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

时间: 2024-11-10 00:52:03

在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建的相关文章

在ASP.NET MVC4中实现同页面增删改查,无弹出框02,增删改查界面设计

在上一篇"在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建"中,已经搭建好了Repository层,本篇就剩下增删改查的界面了......今天的阳光真特么好,写完本篇,好出去在阳光下溜溜狗.散散步什么的,正所谓文武之道一张一弛,走神了,进入正题. 首先是一个View Model,在这里定义验证规则,提交和保存数据的时候还必须和领域模型映射. using System; using System.ComponentModel.DataAnnotat

权限管理系统之LayUI实现页面增删改查和弹出层交互

由于对LayUI框架不太熟悉,昨天抽空看了下LayUI的文档,今天在网上找了使用LayUI进行增删改查相关内容,自己照葫芦画了个瓢,画瓢部分不是很难,主要是下午遇到了一个弹出层的问题耗时比较久. 同一项目,设计风格都差不多,对于涉及单个数据表的页面,基本都是增删改查,布局都是差不多,实际项目中都是复制.粘贴过来改下数据基本就能完成80%,后续就是修修补补或者是要实现一些特殊需求,记得刚参加工作时,老大直接给了一个已经做好的模板页面让我比对着手动敲一遍,当时觉得重复操作没啥用,现在再看觉得作用很大

asp.net中利用JSON进行增删改查中运用到的方法

//asp.net中 利用JSON进行操作, //增加: //当点击"增加链接的时候",弹出增加信息窗口,然后,在窗体中输入完整信息,点击提交按钮. //这里我们需要考虑这些:我会进行异步提交,使用jquery中的方法,$.post("网页名",JSON,callback); //JSON的写法:{"name":name,"id":id},那我们对其进行假设,比方说,表单中的textbox很多,需要我们填写的信息 //也很多,

ASP.NET Web API基于OData的增删改查,以及处理实体间关系

本篇体验实现ASP.NET Web API基于OData的增删改查,以及处理实体间的关系. 首先是比较典型的一对多关系,Supplier和Product. public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Category { get; set; } [ForeignKey("Sup

android中SQLite数据库的增删改查

1.数据库帮助类PersonSQLiteOpenHelper package com.wzw.sqllitedemo.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper

用CI框架向数据库中实现简单的增删改查

以下代码基于CodeIgniter_2.1.3版 用PHP向数据库中实现简单的增删改查(纯代码)请戳 http://www.cnblogs.com/corvoh/p/4641476.html CodeIgniter_2.1.3与PHP5.6的兼容问题请戳 http://www.cnblogs.com/corvoh/p/4649357.html 增: //insert//语法:$bool=$this->db->insert('表名',关联数组); $data=array( 'username'=

用PHP向数据库中实现简单的增删改查(纯代码,待完善)

<?php $con = mysql_connect("localhost:3306","root",""); if (!$con) { die('Could not connect: ' . mysql_error()); } mysql_select_db("test", $con); $result = mysql_query("SELECT * FROM user"); echo "

【ASP】ASP对Access数据库的连接、增删改查及ASP的基本语法

本文讨论的是ASP,而不是Visual Studio写出来的.ASPX也就是ASP.NET. ASP不需要任何插件的支持,关键你是配置好WINDOWS的IIS服务器,把页面扔在上面执行就可以了. 不同WINDOWS系统的IIS服务器配置,除了某些被阉割的WINXP装机版系统之外,都支持IIS服务器配置,都在WINDOWS的组件中,不需要下载任何东西.如何配置IIS服务器不是本文讨论的重点. 一.基本目标 假设Access2007数据库database.mdb中存在表test如下: id为自增列,

数往知来 ASP.NET MVC HtmlHelper、MVC快速增删改查 Cache MVC3客户端验证 MVC隐式异步提交 &lt;二十八&gt;

一.HtmlHelper.MVC快速增删改查 MVC 在MVC里面请求首先到控制器-->然后 -->数据库数据放在APP_DATE文件夹里, -->js.css文件放在content文件夹里 -->控制器放在Controllers里,控制器要以controller结尾 控制器下面的所有方法都称为action 2)webform跟 aspnet MVC:区别请求的地址不一样了 MVC请求的是控制器下面的action webform:aspx页面或者是一般处理程序 -->a标签