2011-06-17 9 views
29

Tak, są questions here i here o tym, jak wstawiać rekordy z dapper-dot-net. Jednak odpowiedzi, choć informacyjne, nie wskazywały na to, że wskazałbym właściwy kierunek. Oto sytuacja: przenoszenie danych z SqlServer do MySql. Odczytywanie zapisów do IEnumerable<WTUser> jest łatwe, ale po prostu nie dostaję czegoś na wstawce. Po pierwsze, 'kod ruchomych rekordy':Jak wstawić kolekcję IEnumerable <T> z dapper-dot-net

// moving data 
Dim session As New Session(DataProvider.MSSql, "server", _ 
          "database") 

Dim resources As List(Of WTUser) = session.QueryReader(Of WTUser)("select * from tbl_resource") 


session = New Session(DataProvider.MySql, "server", "database", _ 
         "user", "[email protected]$$w0rd") 

// *edit* - corrected parameter notation with '@' 
Dim strInsert = "INSERT INTO tbl_resource (ResourceName, ResourceRate, ResourceTypeID, ActiveYN) " & _ 
       "VALUES (@ResourceName, @ResourceRate, @ResourceType, @ActiveYN)" 

Dim recordCount = session.WriteData(Of WTUser)(strInsert, resources) 

// session Methods 
    Public Function QueryReader(Of TEntity As {Class, New})(ByVal Command As String) _ 
                  As IEnumerable(Of TEntity) 
     Dim list As IEnumerable(Of TEntity) 

     Dim cnn As IDbConnection = dataAgent.NewConnection 
     list = cnn.Query(Of TEntity)(Command, Nothing, Nothing, True, 0, CommandType.Text).ToList() 

     Return list 
    End Function 

    Public Function WriteData(Of TEntity As {Class, New})(ByVal Command As String, ByVal Entities As IEnumerable(Of TEntity)) _ 
                  As Integer 
     Dim cnn As IDbConnection = dataAgent.NewConnection 

     // *edit* if I do this I get the correct properties, but no data inserted 
     //Return cnn.Execute(Command, New TEntity(), Nothing, 15, CommandType.Text) 

     // original Return statement 
     Return cnn.Execute(Command, Entities, Nothing, 15, CommandType.Text) 
    End Function 

cnn.Query i cnn.Execute Wytworny wywołać metody rozszerzenie. Teraz, klasa WTUser (uwaga: nazwa kolumny zmienia się z „WindowsName” w SqlServer do „resourceName” w MySQL, stąd dwie właściwości wskazujące na tym samym polu):

Public Class WTUser 
    // edited for brevity - assume the following all have public get/set methods 
    Public ActiveYN As String 
    Public ResourceID As Integer 
    Public ResourceRate As Integer 
    Public ResourceType As Integer 
    Public WindowsName As String 
    Public ResourceName As String 

End Class 

Otrzymuję wyjątek od Dappera : "WTUser nie jest obsługiwany przez Dapper." Ten sposób DataMapper (ruchliwy)

private static Action<IDbCommand, object> CreateParamInfoGenerator(Type OwnerType) 
    { 
     string dmName = string.Format("ParamInfo{0}", Guid.NewGuid()); 
     Type[] objTypes = new[] { typeof(IDbCommand), typeof(object) }; 

     var dm = new DynamicMethod(dmName, null, objTypes, OwnerType, true); // << - here 
     // emit stuff 

     // dm is instanced, now ... 
     foreach (var prop in OwnerType.GetProperties().OrderBy(p => p.Name)) 

W tym momencie OwnerType =

System.Collections.Generic.List`1 [[CRMBackEnd.WTUser, CRMBE, wersja = 1.0.0.0, culture = neutralne TokenKluczaPublicznego = NULL]] mscorlib, Version = 2.0.0.0 Kultura = neutralne TokenKluczaPublicznego = b77a5c561934e089

wydaje podobnie jak OwnerType powinien być CRMBackEnd.WTUser ... nie List<CRMBackEnd.WTUser> ... ??? ponieważ dzieje się tak, że właściwości kolekcji są iterowane: Count, Capacity itd. Czego mi brakuje?

Aktualizacja

Gdybym zmodyfikowany session.WriteData jak:

Public Function WriteData(Of TEntity As {Class, New})(ByVal Command As String, _ 
                 ByVal Entities As IEnumerable(Of TEntity)) _ 
                 As Integer 
    Dim cnn As IDbConnection = dataAgent.NewConnection 
    Dim records As Integer 

    For Each entity As TEntity In Entities 
     records += cnn.Execute(Command, entity, Nothing, 15, CommandType.Text) 
    Next 

    Return records 
End Function 

rekordy są wstawiane ładnie ... ale nie, że to byłoby niezbędne podane przykłady jak:

connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)", 
    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } } 
).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3" 

... od dapper-dot-net

Odpowiedz

45

Właśnie dodałem test na to:

class Student 
{ 
    public string Name {get; set;} 
    public int Age { get; set; } 
} 

public void TestExecuteMultipleCommandStrongType() 
{ 
    connection.Execute("create table #t(Name nvarchar(max), Age int)"); 
    int tally = connection.Execute(@"insert #t (Name,Age) values(@Name, @Age)", new List<Student> 
    { 
     new Student{Age = 1, Name = "sam"}, 
     new Student{Age = 2, Name = "bob"} 
    }); 
    int sum = connection.Query<int>("select sum(Age) from #t drop table #t").First(); 
    tally.IsEqualTo(2); 
    sum.IsEqualTo(3); 
} 

To działa jak reklamowane. Wprowadziłem kilka poprawek do sposobu, w jaki działa multi-exec (więc jest to odrobinę szybsze i obsługuje obiekt []).

Zgaduję, że występowały problemy z powodu braku właściwości getter we wszystkich polach pod numerem WTUser. Wszystkie parametry muszą mieć właściwości czytnika, nie obsługujemy wyciągania tego z pól, wymagałoby to złożonego kroku analizy, aby zachować wydajność.


dodatkowy punkt, spowodowane problemem przechodzi w elegancki param z niepodpartym mapowania.

Na przykład poniższa klasa nie jest obsługiwany jako param:

class Test 
{ 
    public int Id { get; set; } 
    public User User {get; set;} 
} 

cnn.Query("select * from Tests where Id = @Id", new Test{Id = 1}); // used to go boom 

Problem jest, że elegancki nie nie analizowania SQL, przyjmuje wszystkie rekwizyty są ustawiane jako params ale nie był w stanie rozwiązać typ SQL dla User.

Najnowsze rev rozwiązuje ten

+0

edytowany WTUser: wszystkie 'Public' * Pola * są getter/setter ... I edytowany przez wzgląd zwięzłości jest: VB jest rażąco gadatliwy. Wyjaśnię post. ;) – IAbstract

+1

@Sam jest to rozwiązanie ogólne? np. czy działa na Oracle? – MaYaN

+0

Jak mogę odzyskać identyfikator dla podmiotów, które wstawiam? –