c# - Multi-Mapper in Dapper one to many relations -
i trying value of database relation 1 many have object this
student
[table("student")] public class student : istudent { public int id { get; set; } public string lastname { get; set; } public string firstmidname { get; set; } public datetime? enrollmentdate { get; set; } [write(false)] public ienumerable<enrollment> enrollments { get; set; } }
enrollment
[table("enrollment")] public class enrollment { public int id { get; set; } public int courseid { get; set; } public int studentid { get; set; } public string grade { get; set; } public virtual course course { get; set; } public virtual student student { get; set; } }
course
[table("course")] public class course { public int id { get; set; } public string title { get; set; } public int credits { get; set; } public virtual ienumerable<enrollment> enrollments { get; set; } }
here dapper code
_connection = connect.getopenconnection(); const string query = @"select * student stu id = @id " + "select * enrollment enr enr.studentid in (select id student stu id = @id) " + "select * course cou cou.id in (select courseid enrollment studentid = @id)"; var result = _connection.querymultiple(query, new { id = id }) .map<student, enrollment, course, int>( student => student.id, enrollment => enrollment.studentid, course=>course.id, (student, enrollments) => student.enrollments = enrollments , (student, courses) => student.enrollments.foreach(s=>courses.foreach(x=>s.course.title = x.title) ) ).firstordefault();
as per instruction here have extend 3 level hierarchy cant make work
here gridreader mapper
public static ienumerable<tfirst> map<tfirst, tsecond, tthird, tkey> ( sqlmapper.gridreader reader, func<tfirst, tkey> firstkey, func<tsecond, tkey> secondkey, func<tthird, tkey> thirdkey, action<tfirst, ienumerable<tsecond>> addsecond, action<tfirst, ienumerable<tthird>> addthird ) { var result = reader.read<tfirst>().tolist(); var secondmap = reader .read<tsecond>() .groupby(s=>secondkey(s)) .todictionary(g => g.key, g => g.asenumerable()); var thirdmap = reader .read<tthird>() .groupby(t => thirdkey(t)) .todictionary(g => g.key, g => g.asenumerable()); foreach (var item in result) { ienumerable<tthird> third; if (thirdmap.trygetvalue(firstkey(item), out third)) { addthird(item, third); } ienumerable<tsecond> second; if (secondmap.trygetvalue(firstkey(item), out second)) { addsecond(item, second); } } return result.tolist(); }
when run app here result id of 1 notice course title have no value. hope can me thank you.
update 1
i notice getting null value here, doesnt inside if statement
ienumerable<tsecond> second; if (secondmap.trygetvalue(firstkey(item), out second)) { addsecond(item, second); }
update 2
i solve problem here do
var ctr = 0; var mapped2 = conn.querymultiple(query, new {id}) .map<student, enrollment, course, int>( student => student.studentid, enrollment => ctr = enrollment.studentid, course=>course.courseid = ctr, ((student, enrollments) => { student.enrollments = enrollments; }), ((student, courses) => courses.tolist().foreach(s=> student.enrollments.tolist().foreach(x=>x.course = new course { title = s.title }))));
notice added ctr
value of courseid
in enrollment => ctr = enrollment.studentid
. ok face problem, how value of courses
here code
((student, courses) => courses.tolist().foreach(s=> student.enrollments.tolist().foreach(x=>x.course = new course { title = s.title }))
i getting last value
here how solve problem
as above update 2 details added variable ctr
value of courseid
enrollment
, pass course
right value. after face problem how pass value of course
student.enrollment.course
here's how figure out.
i create variable var enrolllst = new list<enrollment>();
hold value of enrollment
first action
((student, enrollments) => { enrolllst = enrollments.tolist(); }),
second action
((student, courses) => { var ctrid = 0; courses.tolist().foreach(cour => { if (cour != null) { enrolllst[ctrid].course = cour; ctrid++; } else { enrolllst[ctrid].course = null; ctrid++; } }); student.enrollments = enrolllst; })).firstordefault();
below whole code
_connection = connect.getopenconnection(); const string query = "select * student stu studentid = @id " + "select * enrollment enr enr.studentid in ( select studentid student stu studentid = @id) " + "select * course cou cou.courseid in (select courseid enrollment studentid = @id)"; var enrolllst = new list<enrollment>(); var ctr = 0; var result = _connection.querymultiple(query, new { id }) .map<student, enrollment, course, int>( student => student.studentid, enrollment => ctr = enrollment.studentid, course => course.courseid = ctr, ((student, enrollments) => { enrolllst = enrollments.tolist(); }), ((student, courses) => { var ctrid = 0; courses.tolist().foreach(cour => { if (cour != null) { enrolllst[ctrid].course = cour; ctrid++; } else { enrolllst[ctrid].course = null; ctrid++; } }); student.enrollments = enrolllst; })).firstordefault();
gridreader mapper extended 3 level hierarchy instructed here
public static ienumerable<tfirst> map<tfirst, tsecond, tthird, tkey> ( sqlmapper.gridreader reader, func<tfirst, tkey> firstkey, func<tsecond, tkey> secondkey, func<tthird, tkey> thirdkey, action<tfirst, ienumerable<tsecond>> addsecond, action<tfirst, ienumerable<tthird>> addthird ) { var result = reader.read<tfirst>().tolist(); var secondmap = reader .read<tsecond>() .groupby(secondkey) .todictionary(g => g.key, g => g.asenumerable()); var thirdmap = reader .read<tthird>() .groupby(thirdkey) .todictionary(g => g.key, g => g.asenumerable()); foreach (var item in result) { ienumerable<tsecond> second; if (secondmap.trygetvalue(firstkey(item), out second)) { addsecond(item, second); } ienumerable<tthird> third; if (thirdmap.trygetvalue(firstkey(item), out third)) { addthird(item, third); } } return result.tolist(); }
Comments
Post a Comment