在我的應用程序中,我想將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方法中看到的那樣,有可能使用參數,但它又是一個測試版本。 –
在你的文章中,你會談論更新,但在代碼中沒有看到單個更新語句。你還提到了其他觸發器的更新。當我們沒有全部信息時,確實很難提供幫助。你能發表更多的細節,以便我們看到問題出在哪裏? –