MVC3+EF5.0 code first+Flexigrid+ajax請求+jquery dialog 增刪改查

本文的目的:

 
  一、MVC3項目簡單配置EF code first生成並初始化數據庫。
  二、利用flexigrid展現並使用ajax展現數據,支持顯示列增減,顯示列排序,顯示列模糊查詢,熟悉表格控件的使用。
  三、利用jquery ajax請求實現增刪查改
  四、利用jquery dialog彈出層實現添加,修改。
  五、擴展方法及表達式樹構建lambda表達式

項目截圖說明

附flexigrid參數說明(能夠去flexigrid.js文件中查看配置):javascript

height: 200, //flexigrid插件的高度,單位爲px
width: 'auto', //寬度值,auto表示根據每列的寬度自動計算,在IE6下建議設置具體值不然會有問題
striped: true, //是否顯示斑紋效果,默認是奇偶交互的形式
novstripe: false,//沒用過這個屬性
minwidth: 30, //列的最小寬度
minheight: 80, //列的最小高度
resizable: false, //resizable table是否可伸縮
url: false, //ajax url,ajax方式對應的url地址
method: 'POST', // data sending method,數據發送方式
dataType: 'json', // type of data loaded,數據加載的類型,xml,json
errormsg: '發生錯誤', //錯誤提高信息
usepager: false, //是否分頁
nowrap: true, //是否不換行
page: 1, //current page,默認當前頁
total: 1, //total pages,總頁面數
useRp: true, //use the results per page select box,是否能夠動態設置每頁顯示的結果數
rp: 25, // results per page,每頁默認的結果數
rpOptions: [10, 15, 20, 25, 40, 100], //可選擇設定的每頁結果數
title: false, //是否包含標題
pagestat: '顯示記錄從{from}到{to},總數 {total} 條', //顯示當前頁和總頁面的樣式
procmsg: '正在處理數據,請稍候 ...', //正在處理的提示信息
query: '', //搜索查詢的條件
qtype: '', //搜索查詢的類別
qop: "Eq", //搜索的操做符
nomsg: '沒有符合條件的記錄存在', //無結果的提示信息
minColToggle: 1, //容許顯示的最小列數
showToggleBtn: true, //是否容許顯示隱藏列,該屬性有bug設置成false點擊頭腳本報錯。
hideOnSubmit: true, //是否在回調時顯示遮蓋
showTableToggleBtn: false, //是否顯示【顯示隱藏Grid】的按鈕
autoload: true, //自動加載,即第一次發起ajax請求
blockOpacity: 0.5, //透明度設置
onToggleCol: false, //當在行之間轉換時,可在此方法中重寫默認實現,基本無用
onChangeSort: false, //當改變排序時,可在此方法中重寫默認實現,自行實現客戶端排序
onSuccess: false, //成功後執行
onSubmit: false, // 調用自定義的計算函數,基本沒用 css

實現步驟

一、配置EF5.0 code first生成並初始化數據庫html

  首先在項目中添加對EF5.0的引用,獲取方式能夠經過nuget包管理器添加或者經過控制檯添加,這裏給出一種方式的截圖。java

編寫實體類(代碼中有註釋說明):jquery

[Table("Students",Schema="xxxx")]//數據庫映射表名及架構
    public class Student
    {
        [Key]//主鍵且自增加
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
        public string Mobile { get; set; }
        public string QQ { get; set; }
        public string Description { get; set; }
    }
View Code

編寫數據庫上下文:web

public class GridDbContext:DbContext
    {
        public GridDbContext():base("name=GridDbContext")//指定EF識別的數據庫鏈接字符串名稱
        {
            Database.SetInitializer<GridDbContext>(new GridDbInitializer());//初始化數據庫,也可在global中設置
        }
        public DbSet<Student> Students { get; set; }
    }
View Code

此處注意如果不指定數據庫鏈接字符串名稱,在web.config中只需將鏈接字符串的名稱與數據庫上下文類的名稱同樣便可。ajax

鏈接字符串:數據庫

<connectionStrings>
    <add name="GridDbContext" connectionString="Data Source=(local);Initial Catalog=XXXX;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
  </connectionStrings>

編寫數據庫表初始化數據填充類:json

public class GridDbInitializer : DropCreateDatabaseIfModelChanges<GridDbContext>
    {
        //初始化數據庫數據
        protected override void Seed(GridDbContext context)
        {
            List<Student> list = new List<Student>(){
             new Student(){Name="張一",Age=18,Address="山東濟南",Mobile="21111111",QQ="3456789",Description="帥哥"},
             new Student(){Name="張二",Age=18,Address="北京東城",Mobile="21111111",QQ="3456789",Description="帥哥"},
             new Student(){Name="張三",Age=18,Address="北京西城",Mobile="21111111",QQ="3456789",Description="美女"},
             new Student(){Name="張四",Age=18,Address="山東濟南",Mobile="21111111",QQ="3456789",Description="美女"},
             new Student(){Name="張五",Age=18,Address="廣東東莞",Mobile="21111111",QQ="3456789",Description="美女"},
             new Student(){Name="張六",Age=18,Address="山東濟南",Mobile="21111111",QQ="3456789",Description="帥哥"},
             new Student(){Name="張七",Age=18,Address="雲南邊境",Mobile="21111111",QQ="3456789",Description="美女"},
             new Student(){Name="張八",Age=18,Address="山東濟南",Mobile="21111111",QQ="3456789",Description="帥哥"},
             new Student(){Name="張九",Age=18,Address="山東濟南",Mobile="21111111",QQ="3456789",Description="帥哥"},
             new Student(){Name="張十",Age=18,Address="山東菏澤",Mobile="21111111",QQ="3456789",Description="美女"},
             new Student(){Name="張十一",Age=18,Address="山東泰安",Mobile="21111111",QQ="3456789",Description="帥哥"},
           };
            list.ForEach(c => context.Students.Add(c));
            context.SaveChanges();
        }
View Code

至此,EF生成數據庫配置完成,咱們只需在controller中隨便寫一個方法調用一下,即可在數據庫中自動生數據庫及表,並初始化數據。架構

二、配置Flexigrid

在模板頁中添加對jquery等js的引用

<script src="../../Scripts/jquery-1.8.0.min.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery-ui-1.8.23.min.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/flexigrid.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/flexigrid.pack.js")" type="text/javascript"></script>
    <link href="@Url.Content("~/Content/flexigrid.css")" rel="stylesheet" type="text/css" />

首先咱們在HomeController中爲Index添加一個視圖,在此視圖中配置flxigrid。

index頁面顯示代碼:

@{
    ViewBag.Title = "Home Page";
}
    <script type="text/javascript">
        $(document).ready(function () {
            $('#students').flexigrid({
                url: '/Home/FlexigridList',
                dataType: 'json',
                colModel: [
                { display: '編號', name: 'ID', width: 40, sortable: true, align: 'left' },
                { display: '姓名', name: 'Name', width: 100, sortable: false, align: 'left' },
                { display: '年齡', name: 'Age', width: 80, sortable: true, align: 'left' },
                { display: '地址', name: 'Address', width: 80, sortable: false, align: 'left' },
                { display: '手機', name: 'Mobile', width: 80, sortable: false, align: 'left' },
                { display: 'QQ', name: 'QQ', width: 80, sortable: false, align: 'left' },
                { display: '描述', name: 'Description', width: 80, sortable: false, align: 'left' }
            ],
                buttons: [
            { name: '添加', bclass: 'add', onpress: button },
            { name: '修改', bclass: 'edit', onpress: button },
            { name: '刪除', bclass: 'delete', onpress: button },
            { separator: true }
            ],
                searchitems: [
                { display: '姓名', name: 'Name' },
                { display: '描述', name: 'Description' }
            ],
                sortname: 'ID',
                sortorder: 'asc',
                usepager: true,
                title: '學生列表',
                useRp: true,
                rp: 10,
                showTableToggleBtn: true,
                width: 1040,
                height: 350,
                checkbox: true,
                rowId: 'ID'
            });
        })
        function button(com,grid) {                
                switch (com) {
                    case "添加":
                        AddOrEdit(0);
                        return;
                    case "修改":
                        var ids = $('tr.trSelected td:first').text();
                        if (ids == undefined) {
                            alert("請選擇一條數據");
                        }
                        else {
                            AddOrEdit(ids);
                        }
                        return;
                    case "刪除":
                        var valueArray = new Array();
                        var list = $('tr.trSelected').each(function () {
                            valueArray.push($(this).find("td:first").text());
                        });
                        if (valueArray.length <= 0) {
                            alert("請選擇一條數據");
                        }
                        else {
                            var idsstring = valueArray.join(',');
                            DeletStudent(idsstring);
                            window.location.reload();
                        }
                        return;
                }
};
        function AddOrEdit(ids) {
            $.ajax({
                type: "GET",
                url: "/home/AddStudent?id="+ids,
                success: function (html) {
                    $("<div class='formtalbe'></div>").html(html)
                                .attr("title", "操做")
                                .dialog({
                                    autoOpen: true,
                                    modal: true,
                                    width: 300,
                                    buttons: {
                                        "肯定": function () {
                                            $(".formtalbe").find("form").submit();
                                            $(".formtalbe").remove();
                                        },
                                        "取消": function () { $(this).dialog('destroy').remove(); $(this).dialog("close"); }
                                    }
                                });
                },
                error: function () {
                    $(".formtalbe").remove();
                    alert("操做失敗!");
                }
            });

        }
        function DeletStudent(idsstring) {
            $.getJSON("/Home/DelStudent?ids=" + idsstring, function (data) {
                if (data == true)
                    alert("刪除成功!");
            });
        }
</script>
<div id="maintable">
    <table id="students" style="display:none"></table>
</div>
View Code

flexigrid的配置說明參考前文給出的配置及js中的配置說明,下面給出重點幾處的說明:

$('#students').flexigrid()將指定表格轉化成flexigrid控件

url: '/Home/FlexigridList',後臺返回表格ajax數據的方法,datatype爲json數據類型

colModel:配置顯示列名稱,後臺返回對應的數據列,大小,是否排序,位置等

buttons:工具欄按鈕

searchitems:設置須要查詢的列

其餘配置不作說明(checkbox有問題。)

配置完成之後,運行程序如今便能程序出flexigrid的樣子了。

接下來咱們爲根據某一顯示列排序及模糊查詢擴展兩個IQueryable<T>的擴展方法,代碼以下:

public static class ExtensionMethods
    {
        //按某一字段排序查詢擴展方法
        public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool asc)
        {
            var type = typeof(T);
            string methodName = asc ? "OrderBy" : "OrderByDescending";
            var property = type.GetProperty(propertyName);
            var parameter = Expression.Parameter(type, "p");
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExp = Expression.Lambda(propertyAccess, parameter);
            MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExp));
            return source.Provider.CreateQuery<T>(resultExp);
        }
        //根據某一字段進行模糊查詢
        public static IQueryable<T> Like<T>(this IQueryable<T> source, string propertyName, string keyword)
        {
            var type = typeof(T);
            var property = type.GetProperty(propertyName);
            var parameter = Expression.Parameter(type, "p");
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            Expression methodExp = Expression.Call(Expression.Property(parameter, type.GetProperty(propertyName)), typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), Expression.Constant(keyword));
            Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(methodExp, parameter);
            return source.Where(lambda);
        }
    }
View Code

後臺Home/FlexigridList獲取數據的方法(代碼中有詳細說明)

//兩種獲取參數的方式,一種在action上面直接接收,另外一種就是用Request.Form()或者Formcollection來接收
        public JsonResult FlexigridList(int page,int rp,string qtype,string query,string sortname,string sortorder)
        {
            //獲取表格控件須要的參數
            //int page = int.Parse(Request.Form["page"]);
            //int rp = int.Parse(Request.Form["rp"]);
            //string qtype = Request.Form["qtype"].ToString();
            //string query = Request.Form["query"].ToString();
            //string sortname = Request.Form["sortname"].ToString();
            //string sortorder = Request.Form["sortorder"].ToString();

            //var q = db.Students.ToList().AsQueryable();
            var q = from c in db.Students
                    select c;
            ////根據某一字段進行模糊查詢,見擴展方法
            if (!string.IsNullOrEmpty(qtype) && !string.IsNullOrEmpty(query))
            {
                q = q.Like(qtype, query);
            }            
            ////按某一字段進行排序
            if (!string.IsNullOrEmpty(sortname) && !string.IsNullOrEmpty(sortorder))
            {
                q = q.OrderBy(sortname, (sortorder == "asc"));
            }
            ////分頁
            q = q.Skip((page - 1) * rp).Take(rp);
            ////構造前臺須要的JSON數據類型
            List<Object> row=new List<Object>();
            foreach (Student stu in q)
            {
                var cells = new List<string>() {stu.ID.ToString(), stu.Name, stu.Age.ToString(), stu.Address, stu.Mobile, stu.QQ, stu.Description };
                row.Add(new { id = stu.ID, cell =cells });
            }
            return Json(new { page=page,total=db.Students.Count(),rows=row}, JsonRequestBehavior.AllowGet);
        }
View Code

此方法的重點在於去前臺參數值,根據某一字段構建排序及模糊查詢,返回前臺須要的json數據等。

文章到此爲止,若是程序正確前臺按自定列排序,查詢,顯示數據等都應該正常。

三、實現增刪改

點擊flexigrid的添加和修改按鈕,經過jquery 的ajax請求,將添加及修改頁面加載到jquery dialog中。demo中單獨爲此了一個 js函數,代碼以下

        function AddOrEdit(ids) {
            $.ajax({
                type: "GET",
                url: "/home/AddStudent?id="+ids,
                success: function (html) {
                    $("<div class='formtalbe'></div>").html(html)
                                .attr("title", "操做")
                                .dialog({
                                    autoOpen: true,
                                    modal: true,
                                    width: 300,
                                    buttons: {
                                        "肯定": function () {
                                            $(".formtalbe").find("form").submit();
                                            $(".formtalbe").remove();
                                        },
                                        "取消": function () { $(this).dialog('destroy').remove(); $(this).dialog("close"); }
                                    }
                                });
                },
                error: function () {
                    $(".formtalbe").remove();
                    alert("操做失敗!");
                }
            });

        }

此方法的關鍵在於ajax請求後臺aciton並將試圖加載在一個jquery dialog中,jquery控制表單提交等,添加後修改判斷經過實體類ID判斷。

後臺添加修改方法:

//添加及修改
        public ActionResult AddStudent(int id=0)
        {
            var stu=id>0?db.Students.Find(id):new Student();
            return View(stu);
        }
        [HttpPost]
        public ActionResult AddStudent(Student student,FormCollection fc)
        {
            TryUpdateModel(student, fc);
            if (student.ID == 0)
                db.Students.Add(student);
            else
                db.Entry(student).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }

添加及修改頁面:

@model FlexGridDemo.Models.Student
@{
    Layout = null;
    }

@using (Html.BeginForm("AddStudent", "Home"))
{
    <table>
        <tr>
        @Html.HiddenFor(m=>m.ID)
            <th>姓名</th>
            <td>@Html.TextBoxFor(m=>m.Name)</td>
        </tr>
        <tr>
            <th>年齡</th>
            <td>@Html.TextBoxFor(m=>m.Age)</td>
        </tr>
        <tr>
            <th>地址</th>
            <td>@Html.TextBoxFor(m=>m.Address)</td>
        </tr>
        <tr>
            <th>手機</th>
            <td>@Html.TextBoxFor(m=>m.Mobile)</td>
        </tr>
        <tr>
            <th>QQ</th>
            <td>@Html.TextBoxFor(m=>m.QQ)</td>
        </tr>
        <tr>
            <th>描述</th>
            <td>@Html.TextBoxFor(m=>m.Description)</td>
        </tr>
    </table>
}
View Code

 

前臺刪除js方法,一樣是ajax提交

function DeletStudent(idsstring) {
            $.getJSON("/Home/DelStudent?ids=" + idsstring, function (data) {
                if (data == true)
                    alert("刪除成功!");
            });
        }

後臺action方法

//批量刪除
        public ActionResult DelStudent(string ids)
        {
            var idarray = ids.Split(',');
            foreach(var id in idarray)
            {
                var temp=db.Students.Find(int.Parse(id));
                db.Entry(temp).State=EntityState.Deleted;
            }
            db.SaveChanges();
            return Json(true);
        }

案例到此結束,flexigrid展現數據,數據的增刪改查都已經實現了。

結語

因爲只是爲了掩飾flexigrid的使用,項目中有不少不合理的地方,已知的問題:flexigrid多選框的問題,添加修改字段沒有添加驗證,添加修改及刪除成功後沒有實現局部刷新等問題。

若有須要可本身擴展。

 DEMO下載:點我下載

歡迎各位有志之士討論批評,如資料有用歡迎推薦,歡迎拍磚。

相關文章
相關標籤/搜索