The problem I have, is that I am currently trying to get a list of objects with multi-mapping. I want get a list of Object A, that has Object B within, and both are saved separately in my database. Below are my objects and Tables.
Objects are:
// Object A
public class TestObject
{
public int objectId { get; set; }
public string name { get; set; }
public ObjectDetail detailId { get; set; }
}
and
// Object B
public class ObjectDetail
{
public int detailId { get; set; }
public string owner { get; set; }
public string description { get; set; }
}
My tables are dbo.testobject with columns "objectId" (primary key int), "name" (nvarchar), "detailId" (int); and dbo.objectdetail with columns "detailId" (primary key int), "owner" (nvarchar), "description" (nvarchar).
So to begin, I have no problems inserting rows into the tables, matching the keys, and querying a single object of TestObject, able to call out all the details including the ones inside the matching ObjectDetail.
However, I am stuck on trying to get a list of TestObject.
What I have done initially, is the code below.
string sql = $"select ob.*, de.* " +
$"from dbo.testobject ob " +
$"left join dbo.objectdetail de " +
$"on ob.detailId = de.detailId ";
using (IDbConnection connection)
{
var selected = connection.Query<TestObject, ObjectDetail, TestObject>(sql,
(test, detail) => { test.detailId = detail; return test; },
splitOn: "detailId");
}
Which returns the error:
System.Data.DataException: 'Error parsing column 2 (detailId=8 - Int32)'
and an Inner Exception ofInvalidCastException: Invalid cast from 'System.Int32' to 'SQLDataAccessDemo.ObjectDetail'.
So I guessed that it might be because of the "detailId" column in dbo.testobject does not match the datatype of detailId in the class TestObject. So then I went back and played around with the code making the changes below.
// I first made changes to the classes
// TestObject is now int Id, string name, ObjectDetail detail
// ObjectDetail object is now int Id, string owner, string description
string sql = $"select ob.*, de.* " +
$"from dbo.testobject ob " +
$"left join dbo.objectdetail de " +
$"on ob.detailId = de.Id ";
using (IDbConnection connection)
{
var selected = connection.Query<TestObject, ObjectDetail, TestObject>(sql,
(test, detail) => { test.detail = detail; return test; });
}
Which works and doesn't give the error.
So my question is, how do I make it work without having to change my initial tables?
Would suggest that you should not name the object property with postfix
Id. Hence yourTestObjectclass should contain a new property:ObjectDetailthat holds the object value.And please use Pascal case to name the properties as following C# naming conventions.
In your Dapper query, works with
splitOn: