update queryasync query multiple inner example c# dapper multi-mapping

multiple - queryasync dapper c#



No se puede hacer que el mapeo mĂșltiple funcione en Dapper (1)

Eso sería porque cambié las API y olvidé actualizar la documentación, corregí el error.

Asegúrese de echar un vistazo a Tests.cs para una especificación actualizada completa.

En particular, la antigua API solía tomar una Action<T,U> para realizar el mapeo, el problema era que se sentía arbitrario e inflexible. No se pudo controlar completamente el tipo de retorno. Las nuevas API toman un Func<T,U,V> . Por lo tanto, puede controlar el tipo que obtiene del asignador y no es necesario que sea un tipo asignado.

Acabo de atar un poco de flexibilidad adicional alrededor del mapeo múltiple, esta prueba debería dejarlo claro:

class Person { public int PersonId { get; set; } public string Name { get; set; } } class Address { public int AddressId { get; set; } public string Name { get; set; } public int PersonId { get; set; } } class Extra { public int Id { get; set; } public string Name { get; set; } } public void TestFlexibleMultiMapping() { var sql = @"select 1 as PersonId, ''bob'' as Name, 2 as AddressId, ''abc street'' as Name, 1 as PersonId, 3 as Id, ''fred'' as Name "; var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address,Extra>> (sql, (p,a,e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First(); personWithAddress.Item1.PersonId.IsEqualTo(1); personWithAddress.Item1.Name.IsEqualTo("bob"); personWithAddress.Item2.AddressId.IsEqualTo(2); personWithAddress.Item2.Name.IsEqualTo("abc street"); personWithAddress.Item2.PersonId.IsEqualTo(1); personWithAddress.Item3.Id.IsEqualTo(3); personWithAddress.Item3.Name.IsEqualTo("fred"); }

Dapper canaliza todas las API de mapeo múltiple a través de un solo método, por lo que si algo falla, terminará en el parámetro 6. La otra pieza del rompecabezas fue que no permití algunas divisiones súper flexibles, que acabo de agregar.

Tenga en cuenta que el splitOn se establecerá de forma predeterminada en Id , lo que significa que tomará una columna llamada id o Id como el primer límite del objeto. Sin embargo, si necesita límites en varias claves primarias que tienen nombres diferentes para decir una asignación múltiple de "3 vías", ahora puede pasar en una lista separada por comas.

Así que si tuviéramos que arreglar lo anterior, probablemente funcionaría lo siguiente:

var student = _conn.Query<Student,Address,Student> ("SELECT s.*, a.* FROM dbo.Student s INNER JOIN dbo.Address a ON s.AddressID = a.AddressID WHERE s.StudentenID = @Id", (stu, adr) => { stu.PrimaryAddress = adr; return stu;}, new { Id = 4711 }, splitOn: "AddressID").FirstOrDefault();

Jugando con Dapper, estoy bastante satisfecho con los resultados hasta ahora, ¡intrigante!

Pero ahora, mi siguiente escenario sería leer datos de dos tablas: una tabla de Student y una de Address .

Student tabla de Student tiene una clave principal de StudentID (INT IDENTITY) de StudentID (INT IDENTITY) , La Address tiene una AddressID (INT IDENTITY) . AddressID (INT IDENTITY) . Student también tiene un FK llamado AddressID enlaza en la tabla de Address .

Mi idea fue crear dos clases, una para cada tabla, con las propiedades que me interesan. Además, puse una propiedad PrimaryAddress de tipo Address en mi clase de Student en C #.

Luego traté de recuperar los datos del alumno y de la dirección en una sola consulta. Imito la muestra que aparece en la página de Github :

var data = connection.Query<Post, User>(sql, (post, user) => { post.Owner = user; }); var post = data.First();

Aquí, se recuperan una Post y un User , y el propietario de la publicación se configura para el usuario, el tipo devuelto es una Post ¿correcto?

Así que en mi código, defino dos parámetros para el método de extensión de Query genérica: un Student como el primero que debe devolverse y una Address como el segundo, que se almacenará en la instancia del estudiante:

var student = _conn.Query<Student, Address> ("SELECT s.*, a.* FROM dbo.Student s INNER JOIN dbo.Address a ON s.AddressID = a.AddressID WHERE s.StudentenID = @Id", (stu, adr) => { stu.PrimaryAddress = adr; }, new { Id = 4711 });

El problema es que me sale un error en Visual Studio:

Usando el método genérico ''Dapper.SqlMapper.Query (System.Data.IDbConnection, string, System.Func, dynamic, System.Data.IDbTransaction, bool, string, int ?, System.Data.CommandType?)'' Requiere 6 argumentos de tipo

Realmente no entiendo por qué Dapper insiste en usar esta sobrecarga con 6 argumentos de tipo ...