c# - how to make changes on an object and its child list property when passing them separately in method? -
i have generic method, takes object , list, list property of object:
public void getsinglelog<tjcls, tlistobj>(int logid, out tjcls log, list<tlistobj> lst) { var json = (from j in context.tbhistorylog j.id == logid select j.objectjson).first(); var lists = context.tbhistorylog_lists.where(x => x.logid == logid).select(x => x.listjson); log = audithelper.deserializeobject<tjcls>(json); foreach (var item in lists) { var listjson = audithelper.deserializeobject<list<tlistobj>>(item); lst.addrange(listjson); } }
i call so:
jclstbinventory olog = new jclstbinventory(); ohistory.getsinglelog(logid, out olog, olog.lstdetails);
the problem log object set, list not. it's returned empty, has data inside getsinglelog
.
the dirty workaround approach
this dirty , inefficient (because use expressions , reflection, slow), allow use (bad) model without changes:
public void getsinglelog<tjcls, tlistobj>(int logid, out tjcls log, expression<func<tjcls, list<tlistobj>>> listsetter) { var json = (from j in context.tbhistorylog j.id == logid select j.objectjson).first(); var lists = context.tbhistorylog_lists.where(x => x.logid == logid).select(x => x.listjson); log = audithelper.deserializeobject<tlistcontainer>(json); var list = lists.selectmany(j => audithelper.deserializeobject<list<tlistobj>>(j)).tolist(); var property = (listsetter.body memberexpression)?.member propertyinfo; if (property == null) throw new exception("expression not reference property"); property.setvalue(log, list, null); }
which can used this:
jclstbinventory olog; ohistory.getsinglelog(logid, out olog, o => o.lstdetails);
the inheritance based approach
this approach more reasonable , use inheritance achieving same result, while keeping model consistent.
you need interface this:
public interface ilistcontainer<titem> { void setlist(list<titem> list); }
and class want retrieve using method must implement it:
public class jclstbinventory : ilistcontainer<myclass> { // ... other properties public list<myclass> lstdetails { get; set; } public void setlist(list<myclass> list) { lstdetails = list; }
so may use simpler approach retrieving list:
public tlistcontainer getsinglelog<tlistcontainer, titem>(int id) tlistcontainer : ilistcontainer<titem> { var json = (from j in context.tbhistorylog j.id == logid select j.objectjson).first(); var lists = context.tbhistorylog_lists.where(x => x.logid == logid).select(x => x.listjson); var log = audithelper.deserializeobject<tlistcontainer>(json); var list = lists.selectmany(j => audithelper.deserializeobject<list<titem>>(j)).tolist(); log.setlist(list); return log; }
using way:
var olog = ohistory.getsinglelog<jclstbinventory, myclass>(logid);
Comments
Post a Comment