我使用现有的数据库项目处理实体框架6.1.3,ASP.NET MVC 5,Code First。我的数据库(SQL Server 2016)包括一个表,该表具有“rowguid”(uniqueidentifier,ROWGUIDCOL)列(以及ID主键列)和“ModifiedDate”(datetime,DEFAULT(getdate))列。尝试在浏览器中创建新记录时,系统会要求用户键入rowguid和ModifiedDate值,而不是自动应用它们的服务器。我尝试了一些我能想到的技巧(我甚至在表中创建了一个AFTER UPDATE触发器来设置日期),但没有成功。
然后我从表的模型类中删除了这些字段并创建了新视图。这就是诀窍,因为现在SQL Server会自动插入值。不幸的是,我不再能够在索引,编辑和详细信息视图中看到这些值。
我该怎么做才能自动插入列值并仍能看到这些值?
这就是“Title”表EF模型的代码(应用程序名称是HSEFCF):
namespace HSEFCF
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Person.Title")]
public partial class Title
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Title()
{
People = new HashSet<Person>();
TitleLocales = new HashSet<TitleLocale>();
}
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public byte TitleID { get; set; }
public Guid rowguid { get; set; }
public DateTime ModifiedDate { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Person> People { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<TitleLocale> TitleLocales { get; set; }
}
}
SQL代码是这样的:
CREATE TABLE [Person].[Title](
[TitleID] [tinyint] IDENTITY(1,1) NOT NULL,
[rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_PersonTitle_PersonTitleID] PRIMARY KEY CLUSTERED
(
[TitleID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [Person].[Title] ADD CONSTRAINT [DF_PersonTitle_rowguid] DEFAULT (newid()) FOR [rowguid]
GO
ALTER TABLE [Person].[Title] ADD CONSTRAINT [DF_PersonTitle_ModifiedDate] DEFAULT (getdate()) FOR [ModifiedDate]
GO
我不介意无法看到rowguid值,但我希望能够看到ModifiedDate值。
我从模型中删除了rowguid列,所以现在SQL插入值本身(我不介意无法看到实际值)。我可以用ModifiedDate做同样的事情,但后来我无法看到它不适合我的值。然后我在我的DbContext文件中插入以下代码,但它不起作用。除了“需要ModifiedDate字段”之外,我没有收到任何错误消息。
public override int SaveChanges()
{
DateTime saveTime = DateTime.Now;
foreach (var entry in this.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added))
{
if (entry.Property("ModifiedDate").CurrentValue == null)
entry.Property("ModifiedDate").CurrentValue = saveTime;
}
return base.SaveChanges();
}
这是控制器代码:
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 HSEFCF;
namespace HSEFCF.Controllers
{
public class TitleController : Controller
{
private HSEFCFContext db = new HSEFCFContext();
// GET: Title
public ActionResult Index()
{
return View(db.Titles.ToList());
}
// GET: Title/Details/5
public ActionResult Details(byte? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Title title = db.Titles.Find(id);
if (title == null)
{
return HttpNotFound();
}
return View(title);
}
// GET: Title/Create
public ActionResult Create()
{
return View();
}
// POST: Title/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "TitleID,ModifiedDate")] Title title)
{
if (ModelState.IsValid)
{
db.Titles.Add(title);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(title);
}
// GET: Title/Edit/5
public ActionResult Edit(byte? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Title title = db.Titles.Find(id);
if (title == null)
{
return HttpNotFound();
}
return View(title);
}
// POST: Title/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "TitleID,ModifiedDate")] Title title)
{
if (ModelState.IsValid)
{
db.Entry(title).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(title);
}
// GET: Title/Delete/5
public ActionResult Delete(byte? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Title title = db.Titles.Find(id);
if (title == null)
{
return HttpNotFound();
}
return View(title);
}
// POST: Title/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(byte id)
{
Title title = db.Titles.Find(id);
db.Titles.Remove(title);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
这是创建视图代码:
@model HSEFCF.Title
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Title</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
这是编辑视图代码:
@model HSEFCF.Title
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Title</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.TitleID)
<div class="form-group">
@Html.LabelFor(model => model.ModifiedDate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ModifiedDate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ModifiedDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
先谢谢,加拉夫。
答案 0 :(得分:1)
要使EF使用服务器端生成的值,您需要在属性上设置DatabaseGenerated
属性。
此外,对于MVC模型绑定,要将值类型视为可选,它需要可以为空。
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public Guid? rowguid { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime? ModifiedDate { get; set; }
虽然这可能会影响您的数据模型。就个人而言,我更喜欢拆分视图和数据模型,因为它允许在任何一方更灵活和装饰。
答案 1 :(得分:0)
我提出了这个解决方案:
我将ModifiedDate属性设置为:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime ModifiedDate { get; set; }
我在数据库中创建了一个触发器来更新ModifiedDate:
CREATE TRIGGER [dbo].[trg_UpdateModifiedDate]
ON [dbo].[Title]
AFTER UPDATE
AS
UPDATE dbo.Title
SET ModifiedDate = GETDATE()
WHERE TitleID IN (SELECT DISTINCT TitleID FROM Inserted)
我将rowguid属性设置为:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public Guid rowguid { get; set; }
CreativeDate和rowguid属性都不包含在create视图中(它们由SQL Server处理)。 ModifiedDate包含在索引和详细信息视图中。