public class SqlDataContext : DbContext
{
public DbSet<Message> Messages { get; set; }
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
и класс хранилища:
public class SqlRepository : IRepository
{
private SqlDataContext _dataContext;
public SqlRepository(SqlDataContext dataContext) {
_dataContext = dataContext;
}
public DbSet<Message> Messages {
get { return _dataContext.Messages; }
}
public void Commit() {
_dataContext.SaveChanges();
}
}
и класс обслуживания:
public class MessagesServices : IMessagesServices
{
#region Repository
private IRepository _repository;
public UsersServices(IRepository repository) {
_repository = repository;
}
#endregion
/// <summary>
/// Update the Message in Repository
/// </summary>
public void Update(Message message) {
if (message != null) {
_repository.Messages.Attach(message);
_repository.Commit();
}
}
}
Если я получу какое-либо сообщение, подобное этому:
public ViewResult Edit(int messageId)
{
var message = _repository.Messages.First(j => j.MessageId == messageId);
message.Text = "Test";
_userService.Update(message);
}
Все будет хорошо, но изменения не сохраняются в базе данных.
Конструктор контроллера сообщений
private IRepository _repository;
private IMessagesServices _messageServices;
public MessagesController(IRepository repository, IMessagesServices messageServices)
{
_repository = repository;
_messageServices = messageServices;
}
хранилище, сервис и контекст данных внедряются структурной картой:
/// <summary>
/// Configuration registry modules for 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 Вы имеете право.
Если я попробую это:
ObjectFactory.GetInstance<SqlDataContext>().Messages.Attach(message);
ObjectFactory.GetInstance<SqlDataContext>().Entry(message).State = EntityState.Modified;
ObjectFactory.GetInstance<SqlDataContext>().SaveChanges();
Они все отлично работают, поэтому у меня есть несколько экземпляров SqlDataContext.
Но это:
For<SqlDataContext>().Use(() => new SqlDataContext());
не помогает. Есть идеи?
Я думаю, проблема здесь
private IRepository _repository;
private IMessagesServices _messageServices;
public MessagesController(IRepository repository, IMessagesServices messageServices)
{
_repository = repository;
_messageServices = messageServices;
}
Поскольку репозиторий здесь внедряется (внутри репозитория внедряется SqlDataContext) и в тот же момент внедряются сервисы (внутри внедренного репозитория, в репозитории 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);
}
результат равен TRUE.
РАБОЧЕЕ РЕШЕНИЕ:
private IRepository _repository;
private IMessagesServices _messageServices;
public MessagesController(IRepository repository)
{
_repository = repository;
_messageServices = ObjectFactory.GetInstance<IUsersServices>();
}
и в классе услуг:
/// <summary>
/// Update the 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();
}
Но есть ли здесь какое-нибудь решение для двух параметров конструктора? И без использования
ObjectFactory.GetInstance<SqlDataContext>().Entry(message).State = EntityState.Modified;