Ja, hier und hier gibt es Fragen zum Einfügen von Datensätzen mit dapper-dot-net. Die Antworten, obwohl informativ, schienen mich nicht in die richtige Richtung zu weisen. Hier ist die Situation: Verschieben von Daten von SqlServer nach MySql. Das Lesen der Datensätze in einen IEnumerable<WTUser>
ist einfach, aber ich IEnumerable<WTUser>
gerade nichts auf der Einfügung. Zuerst der 'Moving Records Code':
// 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", "p@$$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 und cnn.Execute rufen die Dapper-Erweiterungsmethoden auf. Nun, die WTUser-Klasse (Anmerkung: Der Spaltenname wurde von 'WindowsName' in SqlServer in 'ResourceName' in MySql geändert, daher die zwei Eigenschaften, die auf dasselbe Feld zeigen):
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
Ich erhalte eine Ausnahme von dapper: "WTUser wird von Dapper nicht unterstützt." Diese Methode in DataMapper (dapper):
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))
An diesem Punkt ist OwnerType =
System.Collections.Generic.List`1 [[CRMBackEnd.WTUser, CRMBE, Version = 1.0.0.0, Kultur = neutral, PublicKeyToken = null]], mscorlib, Version = 2.0.0.0, Kultur = neutral, PublicKeyToken = b77a5c561934e089
Es scheint, als wäre OwnerType CRMBackEnd.WTUser
... nicht List<CRMBackEnd.WTUser>
... ??? Denn was passiert ist, dass die Collection-Eigenschaften iteriert werden: Anzahl, Kapazität usw. Was fehlt mir?
Aktualisieren
Wenn ich session.WriteData geändert habe als:
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
Datensätze sind schön eingefügt ... aber ich denke nicht, dass dies notwendig wäre, mit Beispielen wie:
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"
... von dapper-dot-net
Ich habe gerade einen Test dafür hinzugefügt:
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);
}
Es funktioniert wie angekündigt. Ich habe ein paar Änderungen an der Arbeitsweise von Multi-Exec vorgenommen (also ein bisschen schneller und unterstützt das Objekt []).
Meine Vermutung ist, dass Sie Probleme hatten, weil Ihnen auf allen Feldern von WTUser
eine Getter-Eigenschaft WTUser
. Alle Parameter müssen Reader-Eigenschaften haben, wir unterstützen nicht das Ziehen aus Feldern, es würde einen komplexen Parsing-Schritt erfordern, um effizient zu bleiben.
Ein weiterer Punkt, der ein Problem verursacht hat, ist die Übergabe eines Parameters mit nicht unterstützter Zuordnung.
Die folgende Klasse wird beispielsweise nicht als Parameter unterstützt:
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
Das Problem ist, dass Dapper das SQL nicht analysiert hat. Es wurde angenommen, dass alle Props als Parameter gesetzt werden können, aber den SQL-Typ für den User
nicht auflösen konnten.
Die neueste Version löst dies auf