我在更新数据方面遇到了问题,因为我在引用多个数据库表的命令上使用了sqlDataAdapter.我收到了错误:
Dynamic sql generation is not supported against multiple base tables
我尝试通过创建一个将多个表组合成一个“表”的视图来处理它,然后我可以将其绑定到GridControl.
插入数据是在视图中使用“而不是”触发器完成的,在该视图中我将适当的数据添加到适当的表中.在普通的t-sql中,插入工作完美无缺.我可以将数据插入到我的视图中,并将其插入到适当的表中.我的sqlDataAdapter应该没有更新问题,因为它正在更新一个“表”,其余的更新由触发器完成.
不幸的是,我仍然收到错误
Dynamic sql generation is not supported against multiple base tables
你知道为什么sqlDataAdapter仍然没有让我更新,甚至认为它现在只更新一个“表” – 视图?
我的代码:
风景:
CREATE view [dbo].[v_TestTypeParameter_grid] as ( select t1.Id,t3.Name,t3.Description,t2.MinValue,t2.MaxValue,t4.Symbol from TestTypes as t1 join TestTypeParameters as t2 on t1.Id = t2.TestType join Parameters as t3 on t2.Parameter = t3.Id left join Units as t4 on t2.Unit = t4.Id )
而不是视图上的触发器:
CREATE TRIGGER [dbo].[tr_TestTypeParameteradded] ON [dbo] [v_TestTypeParameter_grid] INSTEAD OF INSERT AS BEGIN DECLARE @TestTypeId int,@ParameterId int,@UnitId int,@ParameterName varchar(100),@MinValue decimal(18,2),@MaxValue decimal(18,@UnitSymbol varchar(100) SELECT @TestTypeId = Id,@ParameterName = Name,@MinValue = MinValue,@MaxValue = MaxValue,@UnitSymbol = Symbol FROM Inserted; SELECT @ParameterId = Id FROM Parameters WHERE Name = @ParameterName; SELECT @UnitId = Id from Units WHERESymbol = @UnitSymbol; INSERT INTO TestTypeParameters(TestType,Parameter,MinValue,MaxValue,Unit) VALUES(@TestTypeId,@ParameterId,@MinValue,@MaxValue,@UnitId); END
我的绑定代码:
mvarParameterlistadapter = DBService.GetDataAdapter("select * from v_TestTypeParameter_grid where Id = " + mvarTestTypeId); mvarParameterTable = new DataTable(); mvarParameterlistadapter.Fill(mvarParameterTable); gcParameters.DataSource = mvarParameterTable; gcParameters.RefreshDataSource();
DBService.GetDataAdapter方法:
public static sqlDataAdapter GetDataAdapter(String command,DataTable parameters = null) { sqlConnection lvarConnection = GetConnection(); sqlCommand lvarCommand = new sqlCommand(command,lvarConnection); if (parameters != null && parameters.Rows.Count > 0) { foreach (DaTarow lvarRow in parameters.Rows) { lvarCommand.Parameters.AddWithValue("@" + lvarRow[0],lvarRow[1]); } } sqlDataAdapter lvaradapter = new sqlDataAdapter(lvarCommand); sqlCommandBuilder lvarCommandBuilder = new sqlCommandBuilder(lvaradapter); return lvaradapter; }
更新代码:
try { mvarParameterlistadapter.Update(mvarParameterTable); } catch (Exception ex) { // Here,I'm getting the error }
在t-sql中工作的插入:
INSERT INTO v_TestTypeParameter_grid VALUES (2,'Fe','Iron',5.2,7.9,'%')
由于我有几个这样工作的GridControl(使用不同的数据),我试图不为自己生成sqlDataAdapter的select,insert,update和delete命令,而不是那样,我使用sqlCommandBuilder来保持它更简单.
谢谢!
编辑:
(希望)明确表达:
这是我正在研究的GridControl.原谅我的列名,他们是波兰语.
Identyfikator = Id,
纳兹瓦=姓名,
Opis =描述,
最小= MinValue,
Maksimum = MaxValue,
Jednostka =单位
现在,我在GridControl中添加了另一行,它只包含“Nazwa(Name)”和“Opis(Description)”字段.
我正在填写“Identyfikator(Id)”字段,其中包含我想要添加参数的TestType的Id以及其默认值的其他字段.新行自动添加到绑定到GridControl的DataTable中,在用户单击“保存”后,我想使用sqlDataAdapter.Update()方法将这些更改推送到数据库.这是我收到错误的地方:
Dynamic sql generation is not supported against multiple base tables
我希望它能说明我想要实现的目标以及我是如何做到的.
编辑:
解决方法
首先,我创建了一个模仿GridControl的视图.它看起来像这样:
CREATE VIEW [dbo].[v_TestTypeParameter_grid] AS SELECT t1.Id,t2.Unit as Unit,t3.Id AS ParameterId FROM dbo.TestTypes AS t1 INNER JOIN dbo.TestTypeParameters AS t2 ON t1.Id = t2.TestType INNER JOIN dbo.Parameters AS t3 ON t2.Parameter = t3.Id
重要的是视图包含使目标表中的行唯一的ID(在本例中为:TestTypeId和ParameterId).
Dynamic sql generation is not supported against multiple base tables
错误.
我通过在视图上创建INSTEAD OF触发器来跳过它(一个用于插入,更新和删除).
我的触发器看起来像这样(是的,我知道它们应该基于它设置):
插入:
CREATE TRIGGER [dbo].[tr_TestTypeParameteradded] ON [dbo].[v_TestTypeParameter_grid] INSTEAD OF INSERT AS BEGIN DECLARE @TestTypeId int,@UnitId = Unit from Inserted; SELECT @ParameterId = Id from Parameters where Name = @ParameterName; insert into TestTypeParameters(TestType,Unit) values (@TestTypeId,@UnitId); END
更新:
CREATE TRIGGER [dbo].[tr_TestTypeParameterUpdated] ON [dbo].[v_TestTypeParameter_grid] INSTEAD OF UPDATE AS BEGIN DECLARE @TestTypeId int,2) select * from inserted SELECT @TestTypeId = Id,@UnitId = Unit,@ParameterId = ParameterId from Inserted; update TestTypeParameters set MinValue = @MinValue,MaxValue = @MaxValue,Unit = @UnitId where TestType = @TestTypeId and Parameter = @ParameterId; END
删除:
CREATE TRIGGER [dbo].[tr_TestTypeParameterDeleted] ON [dbo].[v_TestTypeParameter_grid] INSTEAD OF DELETE AS BEGIN DECLARE @TestTypeId int,@ParameterId = ParameterId from deleted; delete from TestTypeParameters where TestType = @TestTypeId and Parameter = @ParameterId; END
我还必须改变我创建sqlDataAdapters的方式:
sqlCommand lvarInsert = new sqlCommand( "insert into v_TestTypeParameter_grid values (@Id,@Name,@Description,@Unit,@ParameterId)",DBService.Connection); mvarParameterlistadapter.InsertCommand = lvarInsert; lvarInsert.Parameters.Add("@Id",sqlDbType.Int,5,"Id"); lvarInsert.Parameters.Add("@Name",sqlDbType.NVarChar,"Name"); lvarInsert.Parameters.Add("@Description","Description"); lvarInsert.Parameters.Add("@MinValue",sqlDbType.Decimal,"MinValue"); lvarInsert.Parameters.Add("@MaxValue","MaxValue"); lvarInsert.Parameters.Add("@Unit","Unit"); lvarInsert.Parameters.Add("@ParameterId","ParameterId"); sqlCommand lvarSelect = new sqlCommand("select * from v_TestTypeParameter_grid where Id = " + mvarTestTypeId,DBService.Connection); mvarParameterlistadapter.SelectCommand = lvarSelect; sqlCommand lvarUpdate = new sqlCommand( "update v_TestTypeParameter_grid set Id = @Id,ParameterId = @ParameterId,Name = @Name,Description = @Description,MinValue = @MinValue,Unit = @Unit where Id = @Id and ParameterId = @ParameterId",DBService.Connection); mvarParameterlistadapter.UpdateCommand = lvarUpdate; lvarUpdate.Parameters.Add("@Id","Id"); lvarUpdate.Parameters.Add("@ParameterId","ParameterId"); lvarUpdate.Parameters.Add("@Name","Name"); lvarUpdate.Parameters.Add("@Description","Description"); lvarUpdate.Parameters.Add("@MinValue","MinValue"); lvarUpdate.Parameters.Add("@MaxValue","MaxValue"); lvarUpdate.Parameters.Add("@Unit","Unit"); sqlCommand lvarDelete =new sqlCommand( "delete from v_TestTypeParameter_grid where Id = @Id and ParameterId = @ParameterId",DBService.Connection); mvarParameterlistadapter.DeleteCommand = lvarDelete; lvarDelete.Parameters.Add("@Id","Id"); lvarDelete.Parameters.Add("@ParameterId","ParameterId");
我几乎可以肯定它可以以不同的(更好的)方式完成,但我想分享它,因为它花了我一些时间来修复它,我找不到任何在线解决方案.
如果您对如何改进它有任何想法,请随时发表评论.
请享用!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。