在我的应用程序中,我想将GridControl绑定到包含来自多个数据库表(使用外键引用)的数据的DataTable。使用SqlDataAdapter更新数据库视图
我在更新数据时遇到问题,因为我在引用多个数据库表的命令上使用了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,2),
@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, '%')
因为我有几个GridControls认为这样的工作(使用不同的数据),我想为了不为SqlDataAdapter自己生成select,insert,update和delete命令,而不是使用SqlCommandBuilder来简化它。
谢谢!
编辑:
(希望)把事情说清楚:
这是我工作的GridControl。原谅我的列名,他们用波兰语。 Identyfikator =标识, 由... =名称, OPIS =描述, 最小= MINVALUE, Maksimum = MaxValue的, Jednostka =单位
现在,我加入另一行GridControl只包含“由...(名称)“和”Opis(描述)“字段。
我使用TestType的Id填充“Identyfikator(Id)”字段,我想用它们的默认值添加参数到其他字段。新行被自动添加到绑定到我的GridControl的DataTable,并且在用户单击“Save”后,我想使用SqlDataAdapter.Update()方法将这些更改推送到数据库。这是我得到错误的地方:
Dynamic sql generation is not supported against multiple base tables
我希望它明确了我想要达到的目标以及如何实现目标。
编辑:
我设法找到解决这个问题的办法。你可以在我的答案下面查看它。
你有一个主要的缺陷。你认为只有一行插入。这不是SQL服务器触发器的工作原理。他们每次手术一次。你需要把它写成一个基于单个集合的插入,并去除这些标量变量。看起来像从插入到参数和单位的简单连接将解决触发问题。你也迫切需要阅读有关参数化查询。你发布的内容很容易被sql注入。 –
@SeanLange我知道每个操作都会触发一次sql触发器,这是一个测试版本,我只想查看更新是否能够正常工作,因为我花了数小时试图找到尽可能干净的更新方法。我也知道参数化查询是什么,正如你可以在GetDataAdapter方法中看到的那样,有可能使用参数,但它又是一个测试版本。 –
在你的文章中,你会谈论更新,但在代码中没有看到单个更新语句。你还提到了其他触发器的更新。当我们没有全部信息时,确实很难提供帮助。你能发表更多的细节,以便我们看到问题出在哪里? –