В моем приложении я хочу привязать 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 самостоятельно, вместо этого я использую SqlCommandBuilder, чтобы упростить его.
Спасибо!
EDIT:
К (надеюсь) сделать вещи ясно:
Это GridControl я работаю. Простите меня за имена колонок, они на польском языке. Identyfikator = Id, Nazwa = Имя, Opis = Описание, Минимум = MinValue, Maksimum = MaxValue, Jednostka = Unit
На данный момент, я добавляю еще одну строку в GridControl, который содержит только «Nazwa (Name) "и" Opis (Описание) ".
Я заполняю поле «Identyfikator (Id)» с идентификатором TestType, которое я хочу добавить к параметрам и другим полям с их значениями по умолчанию. Новая строка автоматически добавляется в DataTable, привязанный к моему GridControl, и после того, как пользователь нажимает «Сохранить», я хочу направить эти изменения в базу данных с помощью метода SqlDataAdapter.Update(). Это где я получаю сообщение об ошибке:
Dynamic sql generation is not supported against multiple base tables
Я надеюсь, что это ясно дал понять, что я хочу достичь и как я пытаюсь это сделать.
EDIT:
мне удалось найти решение этой проблемы. Вы можете проверить это в моем ответе ниже.
У вас ОСНОВНАЯ ошибка.Вы предполагаете, что вставляется только одна строка. Это НЕ, как работают SQL-серверы. Они срабатывают один раз за операцию. Вам нужно написать это как единый набор, основанный на вставке, и избавиться от этих скалярных переменных. Похоже, что простое соединение из вставленных в Parameters and Units будет исправлять проблему с триггером. Вам также крайне необходимо прочитать о параметризованных запросах. То, что вы опубликовали, уязвимо для SQL-инъекции. –
@SeanLange Я знаю, что триггеры sql срабатывают один раз за операцию. Это тестовая версия, в которой я просто хотел узнать, работает ли обновление даже после того, как я потратил часы, пытаясь найти способ сделать обновления максимально чистыми. Я также знаю, какие параметризованные запросы есть и как вы можете видеть в методе GetDataAdapter, есть возможность использовать параметры, но опять же, это просто тестовая версия. –
В своем сообщении вы говорите об обновлениях, но я не вижу ни одного оператора обновления в этом коде. Вы также упоминаете что-то о других триггерах в других местах, которые делают обновления. Очень сложно помочь, когда у нас нет всей информации. Можете ли вы опубликовать более подробную информацию, чтобы мы могли увидеть, где проблема? –