在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建
通常,在同一个页面上实现增删改查,会通过弹出框实现异步的添加和修改,这很好。但有些时候,是不希望在页面上弹出框的,我们可能会想到Knockoutjs
,它能以MVVM模式实现同一个页面上的增删改查,再辅以knockout.validation.js
,还可以对Model进行验证。但knockout.validation.js
与ASP.NET MVC
本身的验证没有做到无缝对接,不能形成一个从客户端到服务端连贯、统一的验证解决方案。关于在ASP.NET MVC中使用Knockoutjs
和knockout.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层等"。
下一篇进入增删改查的界面设计。
在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建的更多相关文章
- 在ASP.NET MVC4中实现同页面增删改查,无弹出框02,增删改查界面设计
在上一篇"在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建"中,已经搭建好了Repository层,本篇就剩下增删改查的界面了......今 ...
- 权限管理系统之LayUI实现页面增删改查和弹出层交互
由于对LayUI框架不太熟悉,昨天抽空看了下LayUI的文档,今天在网上找了使用LayUI进行增删改查相关内容,自己照葫芦画了个瓢,画瓢部分不是很难,主要是下午遇到了一个弹出层的问题耗时比较久. 同一 ...
- ASP.NET Web API基于OData的增删改查,以及处理实体间关系
本篇体验实现ASP.NET Web API基于OData的增删改查,以及处理实体间的关系. 首先是比较典型的一对多关系,Supplier和Product. public class Product { ...
- [转]ASP.NET Web API基于OData的增删改查,以及处理实体间关系
本文转自:http://www.cnblogs.com/darrenji/p/4926334.html 本篇体验实现ASP.NET Web API基于OData的增删改查,以及处理实体间的关系. 首先 ...
- 用CI框架向数据库中实现简单的增删改查
以下代码基于CodeIgniter_2.1.3版 用PHP向数据库中实现简单的增删改查(纯代码)请戳 http://www.cnblogs.com/corvoh/p/4641476.html Code ...
- dbutils中实现数据的增删改查的方法,反射常用的方法,绝对路径的写法(杂记)
jsp的三个指令为:page,include,taglib... 建立一个jsp文件,建立起绝对路径,使用时,其他jsp文件导入即可 导入方法:<%@ include file="/c ...
- 快速开发平台WebBuilder中ExtJS表格的增删改查
使用WebBuilder可实现表格的自动增删改查功能,而无需编写前台脚本和后台SQL. WebBuilder开源项目地址:http://www.putdb.com 自动生成的页面: <!DOCT ...
- MVC中的Ajax与增删改查
自入手新项目以来,一直处于加班状态,博客也有两周没更,刚刚完成项目的两个模组,稍有喘息之机,写写关于项目中 的增删改查,这算是一个老生常谈的问题了,就连基本的教材书上都有.刚看书的时候,以为 没什么可 ...
- Android中Sqlite数据库进行增删改查
今天这篇文章写Sqlite数据库,通过一个小案例来完整讲一下数据库常见的CRUD操作. 先对知识点总结: SQLite数据库 轻量级关系型数据库 创建数据库需要使用的api:SQLiteOpenHel ...
随机推荐
- find中的-print0和xargs中-0的奥妙【转】
find cygnus/firmware_cygnus/target/linux/brcm5830/files/arch/arm/mach-iproc/pm_iproc/ -name "*. ...
- MVC Autofac依赖注入
通过Dll实现全部类的属性注入,该演示实例主要通过多层架构中单一的对象方式来演示,没有采取接口的方式, 新建AutoFacHelper类,如下代码: public class AutoFacHelpe ...
- google地图的url参数
Google Maps Intents for Android The Google Maps app for Android exposes several intents that you can ...
- delete/truncate/drop table的区别以及锁在这里的角色
数据库删除语句 Drop/Delete/Truncate比较 Delete :删除数据表中的行(可以删除某一行,也可以在不删除数据表的情况下删除所有行). 删除某一行:Delete from 数据表名 ...
- ThinkPHP中的统计查询方法
• count() 表示查询表中总的记录数 • max() 表示查询某个字段的最大值 • min() 表示查询某个字段的最小值 • avg() 表示查询某个字段的平均值 • sum() 表示求出某个字 ...
- activeMQ安全配置及常见问题解决
https://blog.csdn.net/dandan2zhuzhu/article/details/78461872
- 7-11Zombie's Treasure Chest uva12325
题意 你有一个体积为N的箱子和两种数量无限的宝物 宝物1的体积为s1 价值为v1 宝物2同理 输入均为32位带符号整数 你的任务是计算最多能带走多少价值的宝物 暴力枚举: 首先明白一点 ...
- ubuntu下hadoop,spark配置
转载来自:http://www.cnblogs.com/spark-china/p/3941878.html 在VMWare 中准备第二.第三台运行Ubuntu系统的机器: 在VMWare中构建第 ...
- Python学习笔记之函数式编程
python中的高阶函数 高阶函数就是 变量名指向函数,下面代码中的变量abs其实是一个函数,返回数字的绝对值,如abs(-10) 返回 10 def add(x,y,f): return f(x) ...
- Wannafly 挑战赛 19 参考题解
这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...