我正在使用VS2013并使用EF6构建一个简单的MVC5应用程序(学习C#/ MVC)
该应用很简单。 SQL数据库中有一个表和一个SP,它通过网页向用户提供顺序作业。此SP也将由另一个应用程序调用,因此业务逻辑位于SP中。
SP获取用户名并返回JobNo(PK),其派生为Max(JobNo)+ 1
我使用的是DB First(因为我目前对于使用代码进行迁移到生产已经足够了解,而且几乎所有我要编写的内容都必须与现有的数据库和现有的SP&#39一起使用; S)
我使用ADO.NET从数据库创建了模型,并选择了表格和一些SP&#39。这创建了以下内容:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace JobNoServer.Models
{
using System;
using System.Collections.Generic;
public partial class JobNo
{
public int JobNo1 { get; set; }
public System.DateTime CreateDateTime { get; set; }
public string UserName { get; set; }
}
}
我遇到的问题是,当我拨打SP(用户点击&#34;获取新工作号和#34;)时,我只想传递用户名。 CreateDateTime将是当前日期时间(在SP中设置),JobNo在SP中确定。
我尝试删除类成员中的setter:
public int JobNo1 { get; }
然后我得到了错误&#34;必须声明一个正文,因为它没有标记为抽象或外部&#34;,但无法弄清楚如何解决这个问题。
我遇到的另一个问题是控制器创建了这个Create方法:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "JobNo1,CreateDateTime,UserName")] JobNo jobNo)
{
if (ModelState.IsValid)
{
db.JobNo.Add(jobNo);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(jobNo);
}
但我无法通过工作,因为直到调用Create之后它才会存在。当我从add方法中删除JobNo时,我收到一条消息,指出没有过载占用零参数。当我看到添加它的某些泛型类的定义时,创建视图说工作号是强制性的
public class DbSet<TEntity> : DbQuery<TEntity>, IDbSet<TEntity>, IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable, IInternalSetAdapter where TEntity : class
{
有人能指出我如何使用一个只接受UserName的create方法,调用SP并获取返回值的正确方向吗?
答案 0 :(得分:0)
通过它的外观你已经成功地映射了db,但是如果你的db依赖于存储过程来创建PK而不是它的默认功能MVC可能会有点困惑,这就是你的地方有麻烦。
您是否尝试将存储过程映射到上下文。基本上右键单击您的edmx图表并从数据库&#39;更新。您可以在“存储过程和函数”部分找到SP并添加它,而不是添加表(您已经执行过)。完成。 Here's the MS how to...
如果您映射存储过程,则可以执行以下操作
public JobNo myCreate( DateTime createDT, string uName)
{
int jobNo = 0;
using(Context db = new Context())
{
jobNo = db.yourSP(youParams probably uName, createDT);
}
return new JobNo() { JobNo1 = jobNo, CreateDateTime = createDT, UserName = uName};
}
然后你可以在你的问题中引用Create函数,并将它传递给刚刚创建的JobNo对象。
如果所有其他方法都失败了,您似乎无法映射您的SP,请记住您可以始终默认直接针对您的上下文执行SQL,并以这种方式调用您的SP。
public JobNo myCreate( DateTime createDT, string uName)
{
int jobNo = 0;
using(Context db = new Context())
{
jobNo = db.Database.SqlQuery<int>("YourProcName @param1, @param2",
new SqlParameter("param1", createDT.toString()),
new SqlParameter("param2", uName));
}
return new JobNo() { JobNo1 = jobNo, CreateDateTime = createDT, UserName = uName};
}
答案 1 :(得分:0)
有很多方法可以让我们看一些选项:
//add a post method to the JobNo class (makes controller logic dead simple)...
public partial class JobNo
{
public int JobNo1 { get; set; }
public System.DateTime CreateDateTime { get; set; }
public string UserName { get; set; }
public Task Post(){
using (var db = new My Entities){
//any issues found here are purely Data access related!
db.JobNo.Add(UserName);
await db.SaveChangesAsync();
}
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(JobNo vm)
{
if (ModelState.IsValid)
{
await vm.Post();
RedirectToAction("Index");
}
return View(vm);
}
但首先你必须解决SP想要的不仅仅是1个参数的问题吗?您是否先使用数据库映射SP?来自SP的JobNo课程?似乎存在&#34;阻抗不匹配&#34;