【发布时间】:2014-03-09 23:49:35
【问题描述】:
我有一个DataGridView 绑定到一个BindingSource 绑定到DataMember tbl_Distribution_Orders_Restriction 的DataSource bs_tbl_Series_Manufacturer,它本身就是一个BindingSource,它有一个链接到一个实体的DataSource ,ForeNET.tbl_Series_Manufacturer。有问题的DataGridView 仅显示与bs_tbl_Series_Manufacturer 的当前记录相关的记录。
tbl_Distribution_Orders_Restriction 有如下定义:
CREATE TABLE [Fore].[tbl_Distribution_Orders_Restriction](
[GM_ORDER_NBR] [varchar](50) NOT NULL,
[Include] [bit] NOT NULL,
[AUS_SRS_CD] [varchar](2) NULL,
[ManufacturerID] [tinyint] NULL,
[CNTLG_DLR_CD] [varchar](6) NULL,
[FAWCode] [varchar](15) NULL,
CONSTRAINT [PK_tbl_Distribution_Orders_Restriction_1] PRIMARY KEY CLUSTERED
([GM_ORDER_NBR] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [Fore].[tbl_Distribution_Orders_Restriction] WITH CHECK ADD CONSTRAINT [FK_tbl_Distribution_Orders_Restriction_tbl_Dealer] FOREIGN KEY([CNTLG_DLR_CD])
REFERENCES [Fore].[tbl_Dealer] ([cntlg_dlr_cde])
ALTER TABLE [Fore].[tbl_Distribution_Orders_Restriction] CHECK CONSTRAINT [FK_tbl_Distribution_Orders_Restriction_tbl_Dealer]
ALTER TABLE [Fore].[tbl_Distribution_Orders_Restriction] WITH CHECK ADD CONSTRAINT [FK_tbl_Distribution_Orders_Restriction_tbl_ModelCodes] FOREIGN KEY([FAWCode])
REFERENCES [Fore].[tbl_ModelCodes] ([FAWCode])
ALTER TABLE [Fore].[tbl_Distribution_Orders_Restriction] CHECK CONSTRAINT [FK_tbl_Distribution_Orders_Restriction_tbl_ModelCodes]
ALTER TABLE [Fore].[tbl_Distribution_Orders_Restriction] WITH CHECK ADD CONSTRAINT [FK_tbl_Distribution_Orders_Restriction_tbl_Series_Manufacturer] FOREIGN KEY([AUS_SRS_CD], [ManufacturerID])
REFERENCES [Fore].[tbl_Series_Manufacturer] ([aus_series_cde], [ManufacturerID])
ALTER TABLE [Fore].[tbl_Distribution_Orders_Restriction] CHECK CONSTRAINT [FK_tbl_Distribution_Orders_Restriction_tbl_Series_Manufacturer]
ALTER TABLE [Fore].[tbl_Distribution_Orders_Restriction] ADD CONSTRAINT [DF_tbl_Distribution_Orders_Restriction_Include] DEFAULT ((0)) FOR [Include]
CREATE TRIGGER [Fore].[trg_I_tbl_Distribution_Orders_Restriction]
ON [Fore].[tbl_Distribution_Orders_Restriction]
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
INSERT INTO Fore.tbl_Distribution_Orders_Restriction (GM_ORDER_NBR, [Include], AUS_SRS_CD, ManufacturerID, CNTLG_DLR_CD, FAWCode)
SELECT inserted.GM_ORDER_NBR, inserted.Include, Fore.qry_SOM_OrderInfo.AUS_SRS_CD, Fore.tbl_ModelCodes.ManufacturerID,
Fore.qry_SOM_OrderInfo.CNTLG_DLR_CD, Fore.qry_SOM_OrderInfo.FAWCode
FROM inserted INNER JOIN
Fore.qry_SOM_OrderInfo WITH (NOEXPAND) ON inserted.GM_ORDER_NBR = Fore.qry_SOM_OrderInfo.GM_ORDER_NBR INNER JOIN
Fore.tbl_ModelCodes ON Fore.qry_SOM_OrderInfo.FAWCode = Fore.tbl_ModelCodes.FAWCode
END
CREATE TRIGGER [Fore].[trg_U_tbl_Distribution_Orders_Restriction]
ON [Fore].[tbl_Distribution_Orders_Restriction]
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON
DELETE Fore.tbl_Distribution_Orders_Restriction
FROM deleted INNER JOIN Fore.tbl_Distribution_Orders_Restriction ON Fore.tbl_Distribution_Orders_Restriction.GM_ORDER_NBR=deleted.GM_ORDER_NBR AND Fore.tbl_Distribution_Orders_Restriction.[Include]=deleted.[Include]
INSERT INTO Fore.tbl_Distribution_Orders_Restriction (GM_ORDER_NBR, [Include], AUS_SRS_CD, ManufacturerID, CNTLG_DLR_CD, FAWCode)
SELECT inserted.GM_ORDER_NBR, inserted.Include, qry_SOM_OrderInfo.AUS_SRS_CD, Fore.tbl_ModelCodes.ManufacturerID, Fore.qry_SOM_OrderInfo.CNTLG_DLR_CD, Fore.qry_SOM_OrderInfo.FAWCode
FROM inserted INNER JOIN Fore.qry_SOM_OrderInfo WITH (NOEXPAND)
ON inserted.GM_ORDER_NBR = Fore.qry_SOM_OrderInfo.GM_ORDER_NBR INNER JOIN
Fore.tbl_ModelCodes ON Fore.qry_SOM_OrderInfo.FAWCode = Fore.tbl_ModelCodes.FAWCode
END
我的问题是这样的:
当我从DataGridView 中删除一行时,该行会按预期消失。此时,我的事件代码调用Context.SaveChanges() 但是,该行并没有从数据库中删除,并且下次我打开表单时,我认为我已经删除的所有记录仍然存在。任何时候都不会显示错误消息。
我将Context.Database.Log绑定到调试窗口,发现当我通过DataGridView执行delete时,执行Context.SaveChanges()会产生类似如下日志输出的结果:
UPDATE [Fore].[tbl_Distribution_Orders_Restriction]
SET [AUS_SRS_CD] = NULL, [ManufacturerID] = NULL
WHERE ([GM_ORDER_NBR] = @0)
-- @0: '6W2CAA' (Type = AnsiString, Size = 50)
-- Executing at 12/02/2014 8:15:51 AM +11:00
-- Completed in 142 ms with result: 1
此 SQL 语句的最终结果是,对 [Fore].[tbl_Distribution_Orders_Restriction] 中的“6W2CAA”记录没有任何更改,因为该表具有填充字段 [AUS_SRS_CD] 和 [ManufacturerID](以及其他)的触发器,基于[GM_ORDER_NBR] 值,前一个字段的存在只是为了消除对必须从许多其他表中查找这些值的不可接受的慢存储过程的需要 - 将查找负载转移到 SQL Server 上更可接受插入/更新。
但是,即使这些触发器不存在,如果用户删除然后插入具有相同 [GM_ORDER_NBR] 值的记录,也会发生错误,因为具有相同(主键)[GM_ORDER_NBR] 值的记录会仍然存在,尽管 [AUS_SRS_CD] 和 [ManufacturerID] 值为 NULL。
我原以为实体框架在从 DataGridView 删除后执行的 SQL 语句更像:DELETE FROM [Fore].[tbl_Distribution_Orders_Restriction] WHERE ([GM_ORDER_NBR] = @0)
当我在事件代码中.Remove 一个实体,然后是.SaveChanges,无效的UPDATE 仍然首先出现,然后是DELETE。
如何让实体框架执行正确的DELETE SQL 语句以响应DataGridView 删除,而不是(而不是补充)完全不适当的UPDATE?
【问题讨论】:
-
你的数据源允许删除吗?
-
数据源允许删除 - 我可以使用 SQL 删除相关表,也可以使用 EF 删除其他表。
-
您是否尝试过使用 EF 在不通过 DataGridView 的情况下删除一行?
-
我可以
.Remove一个实体,结果是.Savechanges上的SQL记录被删除 -
这会让我认为问题出在 DataGridView,而不是 EF。
标签: sql-server vb.net winforms datagridview entity-framework-6