Як вставити список C # до бази даних за допомогою Dapper.NET


75

Використовуючи , як я можу вставити в C# Listбазу даних. Раніше без dapper я використовував наведений нижче код, щоб вставити значення Списку в базу даних .

try
{                
    connection.Open();

    for (int i = 0; i < processList.Count; i++)
    {
        string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@Id, @st_Time, @ed_Time, @td_Time)";
        command = new SqlCommand(processQuery, connection);
        command.Parameters.Add("Id", SqlDbType.Int).Value = processList[i].ID;
        command.Parameters.Add("st_Time", SqlDbType.DateTime).Value = processList[i].ST_TIME;
        command.Parameters.Add("ed_Time", SqlDbType.DateTime).Value = processList[i].ED_TIME;
        command.Parameters.Add("td_Time", SqlDbType.DateTime2).Value = processList[i].TD_TIME;
        dataReader.Close();
        dataReader = command.ExecuteReader();
    }

    connection.Close();
}
catch (SqlException ex)
{
    //--Handle Exception
}

Я знайомий з отриманням даних за допомогою dapper, але це моя перша спроба використовувати вставний запит .

Я спробував наведений нижче код, використовуючи Exceuteпосилання на запит, але застряг у циклі; Я думаю, що використовуючи інструмент dapper, немає потреби в циклічному висловлюванні.

connection.Execute(processQuery ... );

РЕДАГУВАТИ:

class ProcessLog
    {
        public int ID { get; set; }
        public DateTime ST_TIME { get; set; }
        public DateTime ED_TIME { get; set; }
        public DateTime TD_TIME { get; set; }
        public string frequency { get; set; }
    }

Будь ласка, порада щодо цього. FYI: Я використовую SQL Server 2008.

Відповіді:


134

Вам довелося б зробити це трохи інакше. У Dapper він відповідає умовам AKA, властивості або імена полів ідентичні параметрам SQL. Отже, припускаючи, що ви мали MyObject:

public class MyObject
{
    public int A { get; set; }

    public string B { get; set; }
}

І припускаючи processList = List<MyObject>, Ви хотіли б це зробити

foreach (var item in processList)
{
    string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
    connection.Execute(processQuery, item);
}

Зверніть увагу, що MyObjectімена властивостей A та B збігаються з назвами параметрів SQL @A та @B.

Якщо ви не хочете перейменовувати об'єкти, ви можете використовувати анонімні типи для здійснення зіставлення замість конкретних типів:

foreach (var item in processList)
{
    string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
    connection.Execute(processQuery, new { A = item.A, B = item.B });
}

РЕДАГУВАТИ:

Відповідно до коментаря Марка Гравелла, ви також можете попросити Dapper зробити цикл за вас:

string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
connection.Execute(processQuery, processList);

141
Насправді, маловідомий факт: dapper буде повторювати для вас ; середнім може бути:connection.Execute("INSERT INTO PROCESS_LOGS VALUES (@A, @B)", processList);
Марк Гравелл

1
@DavidH Я думав, що не буде потреби в циклах?
Правен

4
Боже мій, Марк, ти ніколи не зупиняєшся, щоб вразити мене. Тепер мені доведеться ще раз перевірити весь код, який я написав за останні 10 днів. (Оскільки я вирішив спробувати цю маленьку перлину)
Стів

6
Чи є спосіб імітувати за (@a1, @b1),(@a2, @b2)допомогою Dapper? Я намагаюся використовувати SQL Server MERGE tble USING VALUES (('a1', 'b1'),('a2','b2')) AS foo(a,b) ON tble.a=foo.a WHEN MATCHED.... Якби ні, я б віддав перевагу ітерації та запуску багатьох операторів, ніж використанню тимчасової таблиці, але Dapper створив мій список у дужках було б дуже добре. Я сумнівний, оскільки я думаю, що це стосується постачальника. Хоча MySQL використовує дужки, розділені комами, для вставки декількох рядків, тому, можливо, це не так? ( INS INTO tbl (a,b) VALUES (a1,b1),(a2,b2)).
Кріс,

2
@Mackan dapper не буде, але LINQ: використовувати listOfChildren.Select(childId => new { A = parentId, B = childId})як аргумент
Марк Гравелл

21

Я вважаю, що групове вставлення краще, ніж перебирати список і вставляти по одному.

SqlTransaction trans = connection.BeginTransaction();

connection.Execute(@"
insert PROCESS_LOGS(Id, st_Time, ed_Time, td_Time)
values(@Id, @st_Time, @ed_Time, @td_Time)", processList, transaction: trans);

trans.Commit();

Довідка: https://stackoverflow.com/a/12609410/1136277


3
Я не вірю, що це об'ємна вставка. Виконуються окремі вставки. Див. Коментарі за наданим вами посиланням.
Боб Хорн,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.