asp.net mvc - Update object in Entity Framework -
public class sqldatacontext : dbcontext { public dbset<message> messages { get; set; } protected override void onmodelcreating(system.data.entity.modelconfiguration.modelbuilder modelbuilder) { base.onmodelcreating(modelbuilder); } } and repository class:
public class sqlrepository : irepository { private sqldatacontext _datacontext; public sqlrepository(sqldatacontext datacontext) { _datacontext = datacontext; } public dbset<message> messages { { return _datacontext.messages; } } public void commit() { _datacontext.savechanges(); } } and service class:
public class messagesservices : imessagesservices { #region repository private irepository _repository; public usersservices(irepository repository) { _repository = repository; } #endregion /// <summary> /// update message in repository /// </summary> public void update(message message) { if (message != null) { _repository.messages.attach(message); _repository.commit(); } } } if message this:
public viewresult edit(int messageid) { var message = _repository.messages.first(j => j.messageid == messageid); message.text = "test"; _userservice.update(message); } everything okay, changes not saved database.
message controller constructor
private irepository _repository; private imessagesservices _messageservices; public messagescontroller(irepository repository, imessagesservices messageservices) { _repository = repository; _messageservices = messageservices; } repository, service , data context injected stucture map:
/// <summary> /// configuration registry modules di /// </summary> public class webuiregistry : registry { public webuiregistry() { for<dbcontext>().use(() => new sqldatacontext()); for<irepository>().httpcontextscoped().use<sqlrepository>(); for<iusersservices>().use<usersservices>(); for<imessagesservices>().use<messagesservices>(); for<ijobadvertsservices>().use<jobadvertsservices>(); for<ilog>().use<sqllogservices>(); } } @slauma have right.
if try this:
objectfactory.getinstance<sqldatacontext>().messages.attach(message); objectfactory.getinstance<sqldatacontext>().entry(message).state = entitystate.modified; objectfactory.getinstance<sqldatacontext>().savechanges(); them works fine, have multiple instance of sqldatacontext.
but this:
for<sqldatacontext>().use(() => new sqldatacontext()); don't help. idea?
i think, problem here
private irepository _repository; private imessagesservices _messageservices; public messagescontroller(irepository repository, imessagesservices messageservices) { _repository = repository; _messageservices = messageservices; } because repository here injected (inside repository injected sqldatacontext) , in same moment injected services (inside injected repository, in repository sqldatacontext)
public class messagecontroller : controller { private irepository _repository; private imessagesservices _messagesservices; public messagecontroller(irepository repository, imessagesservices messagesservices) { _repository = repository; _messagesservices = messagesservices; bool samedatacontexts = object.referenceequals(((sqlrepository)_repository)._datacontext, ((sqlrepository)((messagesservices)_messagesservices)._repository)._datacontext); } result true.
working solution:
private irepository _repository; private imessagesservices _messageservices; public messagescontroller(irepository repository) { _repository = repository; _messageservices = objectfactory.getinstance<iusersservices>(); } and in services class:
/// <summary> /// update message in repository /// </summary> public void update(message message) { if (message != null) { _repository.messages.attach(message); objectfactory.getinstance<sqldatacontext>().entry(message).state = entitystate.modified; _repository.commit(); } but here solution 2 constructor parameters ? , non-using
objectfactory.getinstance<sqldatacontext>().entry(message).state = entitystate.modified;
try replace line ...
for<dbcontext>().use(() => new sqldatacontext()); ...by
for<sqldatacontext>().use(() => new sqldatacontext()); (or add line if need dbcontext resolved somewhere else)
your sqlrepository wants have sqldatacontext constructor parameter, not dbcontext. case di container creates 2 new instances of sqldatacontext when irepository gets resolved , when imessagesservices gets resolved, instead of using registered sqldatacontext instance. repository , service class work 2 different data contexts result in failing update.
it's guess, don't know details of structuremap. unity (i more familiar with), not work: unity doesn't inject instances of registered base class @ places derived class required. need register exact class type want inject.
edit: idea check if datacontexts injected repository , service same, instance in edit method of controller:
bool samedatacontexts = object.referenceequals(_repository._datacontext, _messageservices._repository._datacontext); (make _datacontext in repository , _repository in service class public temporarily test.)
this way can distinguish if have injection problem or ef problem.
Comments
Post a Comment