【发布时间】:2015-03-13 19:07:13
【问题描述】:
我正在开发 MVC5/EF 代码优先应用程序。有谁知道如何实现存储过程,以便每当新记录为inserted 或当前记录updated 时,该记录都会存储在我的INV_AssetsHistory 表中?
我的INV_Assets 表定义为:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using GridMvc.DataAnnotations;
using System.Web.Mvc;
using InventoryTracker.Models;
namespace InventoryTracker.Models
{
[GridTable(PagingEnabled = true, PageSize = 30)]
public class INV_Assets
{
// Setting GridColumn Annotations allows you to use AutoGenerateColumns on view to auto create the Grid based on the model.
public int Id { get; set; }
public int Model_Id { get; set; }
[ForeignKey("Model_Id")]
public virtual INV_Models Model { get; set; }
[Required]
public int Manufacturer_Id { get; set; }
[ForeignKey("Manufacturer_Id")]
public virtual INV_Manufacturers Manufacturer { get; set; }
[Required]
public int Type_Id { get; set; }
[ForeignKey("Type_Id")]
public virtual INV_Types Type { get; set; }
[Required]
public int Location_Id { get; set; }
[ForeignKey("Location_Id")]
public virtual INV_Locations Location { get; set; }
public int Vendor_Id { get; set; }
[ForeignKey("Vendor_Id")]
public virtual INV_Vendors Vendor { get; set; }
[Required]
public int Status_Id { get; set; }
[ForeignKey("Status_Id")]
public virtual INV_Statuses Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
[DataType(DataType.MultilineText)]
public string note { get; set; }
public string owner { get; set; }
//[DataType(DataType.Currency)]
//[DisplayFormat(DataFormatString="{0:C}", ApplyFormatInEditMode=true)]
[DisplayFormat(DataFormatString = "{0:#,###0.00}", ApplyFormatInEditMode=true)]
public decimal cost { get; set; }
public string po_number { get; set; }
[DataType(DataType.MultilineText)]
public string description { get; set; }
public int invoice_number{ get; set; }
[Required]
public string serial_number { get; set; }
[Required]
public string asset_tag_number { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? acquired_date { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? disposed_date { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? verified_date { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime created_date { get; set; }
[Required]
public string created_by { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime? modified_date { get; set; }
public string modified_by { get; set; }
// Flag to specify if item is available? (Not signed out, not auctioned, recycled, etc.)
//public bool available { get; set; }
}
}
我的INV_AssetsHistory 表是这样设置的(我认为这是一个独立的表,没有将其链接到其他表的键值;这与INV_Assets 之间的唯一主要区别是Id当前表的字段和用于指定资产的AssetsId):
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using GridMvc.DataAnnotations;
using System.Web.Mvc;
using InventoryTracker.Models;
namespace InventoryTracker.Models
{
public class INV_AssetsHistory
{
public int Id { get; set; }
[Required]
public int AssetId { get; set; }
//public int Model_Id { get; set; }
//[ForeignKey("Model_Id")]
public virtual INV_Models Model { get; set; }
[Required]
//public int Manufacturer_Id { get; set; }
//[ForeignKey("Manufacturer_Id")]
public virtual INV_Manufacturers Manufacturer { get; set; }
[Required]
//public int Type_Id { get; set; }
//[ForeignKey("Type_Id")]
public virtual INV_Types Type { get; set; }
[Required]
//public int Location_Id { get; set; }
//[ForeignKey("Location_Id")]
public virtual INV_Locations Location { get; set; }
//public int Vendor_Id { get; set; }
//[ForeignKey("Vendor_Id")]
public virtual INV_Vendors Vendor { get; set; }
[Required]
//public int Status_Id { get; set; }
//[ForeignKey("Status_Id")]
public virtual INV_Statuses Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
[DataType(DataType.MultilineText)]
public string note { get; set; }
public string owner { get; set; }
//[DataType(DataType.Currency)]
//[DisplayFormat(DataFormatString="{0:C}", ApplyFormatInEditMode=true)]
[DisplayFormat(DataFormatString = "{0:#,###0.00}", ApplyFormatInEditMode = true)]
public decimal cost { get; set; }
public string po_number { get; set; }
[DataType(DataType.MultilineText)]
public string description { get; set; }
public int invoice_number { get; set; }
[Required]
public string serial_number { get; set; }
[Required]
public string asset_tag_number { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? acquired_date { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? disposed_date { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? verified_date { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime created_date { get; set; }
[Required]
public string created_by { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime? modified_date { get; set; }
public string modified_by { get; set; }
}
}
我正在阅读THIS 文章并尝试实现我想要的功能。在我的InventoryTrackerContext.cs 文件中,我有以下内容:
namespace InventoryTracker.DAL
{
public class InventoryTrackerContext : DbContext
{
public InventoryTrackerContext()
: base("InventoryTrackerContext")
{
}
public DbSet<INV_Assets> INV_Assets { get; set; }
public DbSet<INV_Models> INV_Models { get;set; }
public DbSet<INV_Manufacturers> INV_Manufacturers { get;set; }
public DbSet<INV_Types> INV_Types { get; set; }
public DbSet<INV_Locations> INV_Locations { get; set; }
public DbSet<INV_Vendors> INV_Vendors { get; set; }
public DbSet<INV_Statuses> INV_Statuses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<INV_Assets>().MapToStoredProcedures();
}
在阅读这篇文章时,我添加了这个 (modelBuilder.Entity<INV_Assets>().MapToStoredProcedures();) 特定的代码行并更新了我的上下文。现在在我的Server Explorer 连接InventoryTrackerContext 中,我有3 个名为INV_Assets_Delete/Insert/Update 的存储过程。例如Update定义为:
CREATE PROCEDURE [dbo].[INV_Assets_Update]
@Id [int],
@Model_Id [int],
@Manufacturer_Id [int],
@Type_Id [int],
@Location_Id [int],
@Vendor_Id [int],
@Status_Id [int],
@ip_address [nvarchar](max),
@mac_address [nvarchar](max),
@note [nvarchar](max),
@owner [nvarchar](max),
@cost [decimal](18, 2),
@po_number [nvarchar](max),
@description [nvarchar](max),
@invoice_number [int],
@serial_number [nvarchar](max),
@asset_tag_number [nvarchar](max),
@acquired_date [datetime],
@disposed_date [datetime],
@verified_date [datetime],
@created_date [datetime],
@created_by [nvarchar](max),
@modified_date [datetime],
@modified_by [nvarchar](max)
AS
BEGIN
UPDATE [dbo].[INV_Assets]
SET [Model_Id] = @Model_Id, [Manufacturer_Id] = @Manufacturer_Id, [Type_Id] = @Type_Id, [Location_Id] = @Location_Id, [Vendor_Id] = @Vendor_Id, [Status_Id] = @Status_Id, [ip_address] = @ip_address, [mac_address] = @mac_address, [note] = @note, [owner] = @owner, [cost] = @cost, [po_number] = @po_number, [description] = @description, [invoice_number] = @invoice_number, [serial_number] = @serial_number, [asset_tag_number] = @asset_tag_number, [acquired_date] = @acquired_date, [disposed_date] = @disposed_date, [verified_date] = @verified_date, [created_date] = @created_date, [created_by] = @created_by, [modified_date] = @modified_date, [modified_by] = @modified_by
WHERE ([Id] = @Id)
END
根据这篇文章,我假设当我更新我的INV_Asset 记录时,这个过程会自动触发。如果是这样,它并没有像我预期的那样向我的INV_AssetsHistory 表添加记录——查看 SQL 似乎不是所指示的。
我是否需要手动修改 myINV_Assets_Update 存储过程,或者是否有几行我忽略/不知道的简单代码来完成我想要完成的事情?有没有经验更丰富的护理来衡量一下?
我目前正在使用本地 DBContext,但在 PROD 中,表将位于 ORACLE 数据库中。
【问题讨论】:
-
INV_ASSET 上的触发器可以快速简单地完成这项工作。
-
我不确定 EF 是这里的最佳选择,看起来是数据库触发器的完美场景。
-
你们能否提供一个示例或链接来说明如何设置?我对 Sequel Server/Management Studio 有点熟悉,但 ORACLE 和 Toad 对我来说是新技术/工具。
标签: c# oracle entity-framework stored-procedures dbcontext