Здравствуйте, Holms, Вы писали:
H>Можно ли добавить overload для InsertWithIdentity такого вида
H>T InsertWithIdentity<T>()
К сожалению, такое сделать нельзя из-за ограничений C#. Сигнатура метода InsertWithIdentity уже включает обобщенные параметры:
public static object InsertWithIdentity<T>([NotNull] this IValueInsertable<T> source)
public static object InsertWithIdentity<T>([NotNull] this Table<T> target, [NotNull] Expression<Func<T>> setter)
public static object InsertWithIdentity<TSource,TTarget>(
public static object InsertWithIdentity<TSource,TTarget>([NotNull] this ISelectInsertable<TSource,TTarget> source)
Добавление ещё одного параметра заставит явно указывать их все, т.к. в C# нельзя указывать неполный список обобщённых параметров.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>К сожалению, такое сделать нельзя из-за ограничений C#. Сигнатура метода InsertWithIdentity уже включает обобщенные параметры:
IT>
IT>public static object InsertWithIdentity<T>([NotNull] this IValueInsertable<T> source)
IT>public static object InsertWithIdentity<T>([NotNull] this Table<T> target, [NotNull] Expression<Func<T>> setter)
IT>public static object InsertWithIdentity<TSource,TTarget>(
IT>public static object InsertWithIdentity<TSource,TTarget>([NotNull] this ISelectInsertable<TSource,TTarget> source)
IT>
IT>Добавление ещё одного параметра заставит явно указывать их все, т.к. в C# нельзя указывать неполный список обобщённых параметров.
ладно с этим можно прожить, а как насчет такого метода InsertOrUpdate
а то уже устал писать такой код
Здравствуйте, Holms, Вы писали:
H>ладно с этим можно прожить, а как насчет такого метода InsertOrUpdate H>а то уже устал писать такой код
Upsert?
Давайте подумаем как это лучше сделать. Я знаю, что MSSQL 2008 и DB2 поддерживают MERGE и там это можно сделать без проблем. А как быть с другими провайдерами? Какой код генерировать?
Если нам не помогут, то мы тоже никого не пощадим.
IT>Давайте подумаем как это лучше сделать. Я знаю, что MSSQL 2008 и DB2 поддерживают MERGE и там это можно сделать без проблем. А как быть с другими провайдерами? Какой код генерировать?
Я бы генерировал для всех тот-же код как и у меня в вопросе. т.е. пытаемся делать Update если ничего небыло делаем Insert.
Здравствуйте, IT, Вы писали:
IT>Давайте подумаем как это лучше сделать. Я знаю, что MSSQL 2008 и DB2 поддерживают MERGE и там это можно сделать без проблем. А как быть с другими провайдерами? Какой код генерировать?
В MySql:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Здравствуйте, MozgC, Вы писали:
IT>>Давайте подумаем как это лучше сделать. Я знаю, что MSSQL 2008 и DB2 поддерживают MERGE и там это можно сделать без проблем. А как быть с другими провайдерами? Какой код генерировать?
MC>В MySql:
MC>
INSERT INTO table (a,b,c) VALUES (1,2,3)
MC> ON DUPLICATE KEY UPDATE c=c+1;
Здравствуйте, IT, Вы писали: IT>Тогда этот код надо ещё как-то уметь возвращать.
Пример нехороший, вот я как-то так это вижу:
[TableName(Name="custpercents")]
public partial class Custpercent
{
[Identity, PrimaryKey(1)] public int ID { get; set; } // int(10)public int CustomerID { get; set; } // int(10)public int SupplierID { get; set; } // int(10)public int Perc { get; set; } // int(10)public DateTime TS { get; set; } // timestamp
}
db.UpdateOrInsert(custpercent); // need also support UpdateOrInsertWithIdentity()
генерирует SQL (mysql):
INSERT INTO custpercets
(CustomerID, SupplierID, Perc, TS)
VALUES
(75, 15, 10, '2011-03-24 22:07:20')
ON DUPLICATE KEY UPDATE
CustomerID = 75, SupplierID = 15, Perc = 10, TS = '2011-03-24 22:07:20'
В моем случае на CustomerID & SupplierID стоит составной уникальный индекс, поэтому в части ON DUPLICATE KEY UPDATE их можно было бы не писать, но думаю это будет слишком заморочно для BLT, так что пусть повторяются.
Второй пример (когда нет полного объекта):
db.Custpercents.InsertOrUpdate(
() => new Custpercent
{
CustomerID = 75,
SupplierID = 15,
Perc = 10
});
SQL:
INSERT INTO custpercets
(CustomerID, SupplierID, Perc)
VALUES
(75, 15, 10)
ON DUPLICATE KEY UPDATE
CustomerID = 75, SupplierID = 15, Perc = 10
Думаю что как-то так, может что-то не учел..
Для сравнения, вот как приходится делать сейчас
using (var db = new DataModel())
{
int rowsUpdated = db.Custpercents
.Where(cp => cp.CustomerID == customerID && cp.SupplierID == supplierID)
.Update(cp => new Custpercent {Perc = profitPercent});
if (rowsUpdated == 0)
{
db.Custpercents.Insert(() => new Custpercent
{
CustomerID = customerID,
SupplierID = supplierID,
Perc = profitPercent
});
}
}
По поводу востребованности данной фичи — у меня на реальном проекте ON DUPLICATE KEY UPDATE встречается в 4-5% запросов, т.е. относительно часто.
К тому же оно избавляет от лишнего round-tripа на сервер.
Здравствуйте, IT, Вы писали:
IT>Давайте подумаем как это лучше сделать. Я знаю, что MSSQL 2008 и DB2 поддерживают MERGE и там это можно сделать без проблем. А как быть с другими провайдерами? Какой код генерировать?
Игорь, сорри за назойливость, но есть ли надежда что будет поддержка Merge? А то прямо грустно писать двухэтажные запросы с 2 раундтрипами на сервер (особенно когда двухзвенка). Причем желательно делать чтобы было именно одним запросом, чтобы не было лишних раундтрипов — насколько я понимаю во всех основных БД это поддерживается (в SQL Server и Oracle — Merge, в MySql — ON DUPLICATE KEY UPDATE), к тому же если не делать одним запросом то можно нарваться на race condition. Чуть выше я писал как я это вижу на примере MySql.