2011-06-17 1 views
29

Oui, questions here et here pour savoir comment insérer des enregistrements avec dapper-dot-net. Cependant, les réponses, bien qu'informatives, ne semblaient pas me diriger dans la bonne direction. Voici la situation: déplacer des données de SqlServer à MySql. Lire les enregistrements dans un IEnumerable<WTUser> est facile, mais je ne reçois tout simplement pas quelque chose sur l'insertion. Tout d'abord, le 'code des dossiers en mouvement':Comment insérer une collection IEnumerable <T> avec 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 et cnn.Execute appeler les méthodes d'extension pimpants. Maintenant, la classe WTUser (note: le nom de colonne changé de « WindowsName » dans SqlServer à « ResourceName » dans MySql, donc les deux propriétés pointant vers le même champ):

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 

Je reçois une exception dapper : "WTUser n'est pas pris en charge par Dapper." Cette méthode DataMapper (pimpant):

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)) 

A ce stade, OwnerType =

System.Collections.Generic.List`1 [[CRMBackEnd.WTUser, CRMBE, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]], mscorlib, version = 2.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089

Il semble comme OwnerType devrait être CRMBackEnd.WTUser ... pas List<CRMBackEnd.WTUser> ... ??? car ce qui se passe, c'est que les propriétés de la collection sont itérées: nombre, capacité, etc. Qu'est-ce qui me manque?

Mise à jour

Si je session.WriteData modifié comme:

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 

sont insérées bien ... mais je ne pensais pas que ce serait comme exemples donnés nécessaires:

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" 

... de dapper-dot-net

Répondre

45

Je viens d'ajouter un test pour cela:

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); 
} 

Il fonctionne comme annoncé. J'ai apporté quelques modifications à la façon dont fonctionne le multi-exec (donc c'est un peu plus rapide et supporte l'objet []). Je suppose que vous aviez des problèmes car il vous manquait une propriété getter dans tous les champs de WTUser. Tous les paramètres doivent avoir des propriétés de lecteur, nous ne prenons pas en charge l'extraction des champs, cela nécessite une étape d'analyse complexe pour rester efficace.


Un point supplémentaire qui a provoqué un problème est de passer un paramètre dapper avec un mappage non pris en charge.

Par exemple, la classe suivante est pas pris en charge comme 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 

Le problème est que pimpant ne pas Parse SQL, il a assumé tous les accessoires sont réglables comme params, mais n'a pas pu résoudre le type SQL pour User.

Dernières rev résout ce

+0

Edité WTUser: tous les 'Public' * Les champs * sont getter/setter ... J'édité pour souci de concision: VB est grossièrement bavard. Je vais clarifier le message. ;) – IAbstract

+1

@Sam est cette solution générique? c'est-à-dire fonctionne-t-il sur Oracle? – MaYaN

+0

Comment récupérer l'ID pour les entités que j'insère? –

Questions connexes