Всем привет.
Давно хотел попробовать эту замечательную библиотеку в реальном проекте. И тут как раз подвернулась такая возможность. Использую БД Оракл. Посмотрел примеры. Все очень просто и круто.
Сделал класс доступа к данным, добавил туда метод для вставки записи через linq2db. На таблицах используется триггер insert before, который из сиквенса добавляет ид и возвращает его. В самом коде используется метод InsertWithIdentity.
Разобрался с логированием sql, чтобы в файлик писался код, сгенерированный библиотекой.
Все, так как описано в блоге:
http://blog.linq2db.com/2015/05/linq-crud-operations.html
using (var db = new DataConnection())
{
object identity = db.GetTable<TestTable>()
.InsertWithIdentity(() => new TestTable
{
Name = "Crazy Frog",
CreatedOn = Sql.CurrentTimestamp
});
}
DECLARE @IDENTITY_PARAMETER Decimal
SET @IDENTITY_PARAMETER = NULL
INSERT INTO TestTable
(
Name,
CreatedOn
)
VALUES
(
'Crazy Frog',
CURRENT_TIMESTAMP
)
RETURNING
ID INTO :IDENTITY_PARAMETER
Написал, все работает. Потом присмотрелся... И думаю: а какого фига не используются bind-переменные?!.. Это был для меня прям удар в спину. Тут же ведь значения из полей модели прямо вставляются в sql. Вот это косяк! И что интересно, метод Insert генерит SQL с bind-переменными! Но он не очень удобный, потому что не возвращает ид записи. Пришлось его все-таки использовать (сначала sequence дергать, потом ид передавать).. Но я в шоке: почему бинд-переменные не используются??! Да, там есть эскейпинг значений, но гарантируется ли отсутствие SQL injection? Или я напрасно переживаю?.. К тому же, насколько я знаю, бинд-переменные используются ещё для кэширования SQL оракулом... Просто у меня волосы на голове шевельнулись, когда я увидел, что значения не заданы в переменных, а вставляются прямо в текст! Это же ведь такой лоховский косяк.
Что скажете? Или никто не использует InsertWithIdentity?
Вот здесь же все в порядке:
DECLARE @Name Varchar2 -- String
SET @Name = 'Crazy Frog'
DECLARE @Description Varchar2 -- String
SET @Description = NULL
DECLARE @CreatedOn TimeStamp -- DateTime
SET @CreatedOn = NULL
INSERT INTO TestTable
(
Name,
Description,
CreatedOn
)
VALUES
(
:Name,
:Description,
:CreatedOn
)