实体框架,rowguid和ModifiedDate

时间:2016-09-05 06:31:59

标签: sql-server asp.net-mvc entity-framework-6

我使用现有的数据库项目处理实体框架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")
}

先谢谢,加拉夫。

2 个答案:

答案 0 :(得分:1)

要使EF使用服务器端生成的值,您需要在属性上设置DatabaseGenerated属性。

此外,对于MVC模型绑定,要将值类型视为可选,它需要可以为空。

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public Guid? rowguid { get; set; }

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime? ModifiedDate { get; set; }

虽然这可能会影响您的数据模型。就个人而言,我更喜欢拆分视图和数据模型,因为它允许在任何一方更灵活和装饰。

答案 1 :(得分:0)

我提出了这个解决方案:

  1. 我将ModifiedDate属性设置为:

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime ModifiedDate { get; set; }
    
  2. 我在数据库中创建了一个触发器来更新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)
    
  3. 我将rowguid属性设置为:

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public Guid rowguid { get; set; }
    
  4. CreativeDate和rowguid属性都不包含在create视图中(它们由SQL Server处理)。 ModifiedDate包含在索引和详细信息视图中。