【问题标题】:Bind Kendo Grid using Linq to EF query in MVC 5在 MVC 5 中使用 Linq 将 Kendo Grid 绑定到 EF 查询
【发布时间】:2014-10-20 04:37:57
【问题描述】:

来了。我是 MVC 和 EF 的新手,正在尝试构建我的第一个项目,该项目将允许批量编辑公司信用卡交易。 Kendo Grid 似乎是完成这项工作的最佳方法。

查询采用在查询字符串中传递的两个参数(accountID 和语句日期)。我已经能够将网格绑定到模型并让它显示正确的事务。接下来,我需要对其进行配置以进行批量编辑。我被困在这一步。 目前有两个问题:

  1. 无法让网格绑定到 Transaction_Read 方法(返回空网格)。 index 方法可以将事务绑定到网格,但不能在 Json 中。
  2. 无法让网格进行批量更新。它将一直到达 .SaveChanges 函数,但实际上不会更新任何字段。

我的模特:

namespace intranetMVC.Models
{
using System;
using System.Collections.Generic;


public partial class CorpCardTransaction
{
    public int ID { get; set; }
    public System.DateTime ImportDate { get; set; }
    public string AccountID { get; set; }
    public string CardHolderName { get; set; }
    //[DataType(DataType.Date)]
    public Nullable<System.DateTime> StatementDate { get; set; }
    public Nullable<short> StatementRecordNum { get; set; }        
    public Nullable<System.DateTime> PostDate { get; set; }        
    public Nullable<System.DateTime> TranDate { get; set; }
    public string Payee { get; set; }
    public string Description { get; set; }
    public Nullable<decimal> Amount { get; set; }
    public string GL_Account { get; set; }
    public Nullable<short> BranchCode { get; set; }
    public Nullable<bool> Receipt { get; set; }        
    public Nullable<System.DateTime> BackDate { get; set; }
    public Nullable<System.DateTime> SubmitDate { get; set; }
    public Nullable<System.DateTime> ProcessDate { get; set; }
    public string MemberNum { get; set; }
    public string Username { get; set; }
}
}

CorpCardTransactionsController.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using intranetMVC.Models;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Microsoft.AspNet.Identity;

namespace intranetMVC.Controllers
{
public class CorpCardTransactionsController : Controller
{
    private ExpenseReportingEntities db = new ExpenseReportingEntities();       

    public ActionResult Index(string AccountID, DateTime StatementDate)
    {
        //var loginName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\');
        //var username = loginName.Last() + "@xxxx.com";
        var username = "xxxx@xxxx.com";
        var stmtDate = StatementDate;
        var q = from b in db.CorpCardTransactions
                where b.Username == username && b.StatementDate == StatementDate && b.AccountID == AccountID && !b.SubmitDate.HasValue
                select b;
        return View(q.ToList());            
    }
    [HttpGet]
    public ActionResult Transaction_Read([DataSourceRequest] DataSourceRequest request, string AccountID, DateTime StatementDate)
    {
        //var loginName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\');
        //var username = loginName.Last() + "@xxxx.com";
        var username = "xxxx@xxxx.com";
        var stmtDate = StatementDate;
        var q = from b in db.CorpCardTransactions
                where b.Username == username && b.StatementDate == StatementDate && b.AccountID == AccountID && !b.SubmitDate.HasValue
                select b;            
        return View(q.ToList());
        //IQueryable<CorpCardTransaction> transactions = q.ToList();
        //DataSourceResult result = transactions.ToDataSourceResult(result);
        //return Json(result);
    }

    [HttpPost]
    public ActionResult Transaction_Update([DataSourceRequest]DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<CorpCardTransaction> corpCardTransaction)
    {

        var entities = new List<CorpCardTransaction>();
        if (ModelState.IsValid)
        {
            using (db)
            {
                foreach (var transaction in corpCardTransaction)
                {
                    var entity = new CorpCardTransaction
                    {
                        ID = transaction.ID,
                        Description = transaction.Description,
                        GL_Account = transaction.GL_Account,
                        BranchCode = transaction.BranchCode,
                        Receipt = transaction.Receipt
                    };
                    entities.Add(entity);
                    db.CorpCardTransactions.Attach(entity);
                    db.Entry(entity).State = EntityState.Modified;
                }
                db.SaveChanges();
            }
        }
        return Json(entities.ToDataSourceResult(request, ModelState, transaction => new CorpCardTransaction
        {
            ID = transaction.ID,
            Description = transaction.Description,
            GL_Account = transaction.GL_Account,
            BranchCode = transaction.BranchCode,
            Receipt = transaction.Receipt
        }));
    }
}

}

index.cshtml 查看

@*@model IEnumerable<intranetMVC.Models.CorpCardTransaction>*@

@{
ViewBag.Title = "Index";
}

<h2>Corporate Card Transactions</h2>

@(Html.Kendo().Grid<intranetMVC.Models.CorpCardTransaction>()>
.Name("gvTransactions")    
.Columns(columns => 
{
    columns.Bound(c => c.ID);
    columns.Bound(c => c.AccountID);
    columns.Bound(c => c.CardHolderName);
    columns.Bound(c => c.StatementDate).Format("{0:MM/dd/yyyy}");
    columns.Bound(c => c.PostDate).Format("{0:MM/dd/yyyy}");
    columns.Bound(c => c.TranDate).Format("{0:MM/dd/yyyy}");
    columns.Bound(c => c.Payee);
    columns.Bound(c => c.Amount);
    columns.Bound(c => c.Description);
    columns.Bound(c => c.GL_Account);
    columns.Bound(c => c.BranchCode);
    columns.Bound(c => c.Receipt);
})
    .ToolBar(toolBar => 
    {
        toolBar.Save();                      
    })        
    .Editable(editable => editable.Mode(GridEditMode.InCell))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Batch(true)
        .Events(events => events.Error("error_handler"))            
        .Model(model =>
        {
            model.Id(c => c.ID);
            model.Field(c => c.AccountID).Editable(false);
            model.Field(c => c.CardHolderName).Editable(false);
            model.Field(c => c.StatementDate).Editable(false);
            model.Field(c => c.PostDate).Editable(false);
            model.Field(c => c.TranDate).Editable(false);
            model.Field(c => c.Payee).Editable(false);
            model.Field(c => c.Amount).Editable(false);
        })
          .Read("Transaction_Read", "CorpCardTransactions")
          .Update("Transaction_Update", "CorpCardTransactions")            
    )
)
<script type="text/javascript">
function error_handler(e) {
    if (e.errors) {
        var message = "Errors:\n";
        $.each(e.errors, function (key, value) {
            if ('errors' in value) {
                $.each(value.errors, function() {
                    message += this + "\n";
                });
            }
        });
        alert(message);
    }
}

我是否在视图中正确绑定了网格?

我已经用谷歌搜索了尽可能多的不同方式,但没有找到我想要做的事情的答案。我认为我的更新功能不起作用,因为网格最初没有与 Json 结果绑定。不知道如何将我的 Linq 到 EF 查询作为 Json 返回到网格。在那之后,似乎应该有一种更简单的方法来进行批量更新。

【问题讨论】:

  • 我会把剑道扔出窗外,留胡子。 ASP.NET MVC 和 javascript 摇滚 :) 你将获得完全的控制权。
  • 您需要将模型传递给网格 @(Html.Kendo().Grid(Model)> 并且您的 Transaction_Read 返回类型错误。应该返回结果。 ToDataSourceResult(请求)

标签: c# linq entity-framework asp.net-mvc-5 kendo-grid


【解决方案1】:
[HttpGet]
    public ActionResult Transaction_Read([DataSourceRequest] DataSourceRequest request, string AccountID, DateTime StatementDate)
    {
        //var loginName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\');
        //var username = loginName.Last() + "@xxxx.com";
        var username = "xxxx@xxxx.com";
        var stmtDate = StatementDate;
        var q = from b in db.CorpCardTransactions
                where b.Username == username && b.StatementDate == StatementDate && b.AccountID == AccountID && !b.SubmitDate.HasValue
                select b;            
        return Json(q.ToList().ToDataSourceResult(request));
    }

如需更新,请检查if (ModelState.IsValid) { .... }是否有错误

用下面的代码替换你的uysing (db) 块(我没有测试这个代码)

using (db)
            {
                foreach (var transaction in corpCardTransaction)
                {
                    var entity = new CorpCardTransaction
                    {
                        ID = transaction.ID,
                        Description = transaction.Description,
                        GL_Account = transaction.GL_Account,
                        BranchCode = transaction.BranchCode,
                        Receipt = transaction.Receipt
                    };
                    db.CorpCardTransactions.Add(entity);
                    db.SaveChanges();
                }
            }

【讨论】:

  • 谢谢哈博。我将视图中的网格语句更改为:@(Html.Kendo().Grid&lt;intranetMVC.Models.CorpCardTransaction&gt;(Model),但随后出现以下错误:CS1977: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type,如果我从解析中删除模型,它将显示没有任何数据且没有错误的网格。跨度>
  • if (ModelState.IsValid) 没有错误,它实际上一直运行到具有所有正确变量值的db.SaveChanges(); 函数,但没有对数据库进行任何更改。没有错误被抛出。关于如何解决这个问题的任何想法?我的 Transaction_Update ActionResult 看起来还好吗?
  • 不,不是。在实体框架中,您必须一次添加/更新一条记录。更新了我的更新答案
  • 谢谢!!!!这完全有道理,而且有效!!!非常感谢您抽出宝贵的时间 HaBo,相应地标记答案。
  • 更新:它实际上使它通过了 db.savechanges() 函数,并且它保留在以前没有做过的网格中,但它实际上并没有写回数据库:( 想法?我认为 EF 应该正确处理这个问题?
猜你喜欢
  • 1970-01-01
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 2013-03-15
相关资源
最近更新 更多