L2S DataContext out of synch: row not found or changed - asp.net-mvc

Psssst...!
Read on, by all means. But I can tell you here that the problem had nothing to do with the DataContext, but with Dependency Injection. I have left the question up, as it documents one possible issue with the "row not found or changed error" that has nothing to do with real world concurrency conflicts.
It seems the problems have been caused by badly written dependency injection. Or rather, I am beginning to believe, by default lifecycle management by the DI container I used.
The problem was that I used a DataContext as a constructor argument that was supplied by Ninject. It seems that the default behaviour was to cache this DataContext, leading to all manner of unexpected behaviour. I will ask a separate question about this.
Anyway, what follows is my original question, which as you will see, misses the real cause of the issue by a mile...
The Problem
I am getting a number of errors that imply that the DataContext, or rather, the way I am using the DataContext is getting out of synch.
The error occurs on db.SubmitChanges() where db is my DataContext instance. The error is:
Row not found or changed.
The problem only occurs intermitently, for example, adding a row then deleting it. If I stop the dev server and restart, the added row is there and I can delete it no problem.
Ie, it seems that the problem is related to the DataContext losing track of the rows that have been added.
IMPORTANT:
Before anyone votes to close this thread, on the basis of it being a duplicate, I have checked the sql server profiler and there is no "Where 0 = 1" in the SQL.
I have also recreated the dbml file, so am satisfied that the database schema is in synch with the schema represented by the dbml file.
Ie, no cases of mismatched nullable/not nullable columns, etc.
My Diagnosis (for what it is worth):
The problem seems (to me) related to how I am using the DataContext. I am new to MVC, Repositories and Services patterns, so suspect that I have wired things up wrong.
The Setup
Simple eLearning app in its early stages. Pupils need to be able to add and delete courses (Courses table) to their UserCourses.
To do this, I have a service that gets a specific DataContext instance Dependency Injected into its constructor.
Service Class Constructor:
public class SqlPupilBlockService : IPupilBlockService
{
DataContext db;
public SqlPupilBlockService(DataContext db)
{
this.db = db;
CoursesRepository = new SqlRepository<Course>(db);
UserCoursesRepository = new SqlRepository<UserCourse>(db);
}
// Etc, etc
}
The CoursesRepository and UserCoursesRepository are both private properties of the service class that are of type IRepository (just a simple generic repository interface).
SqlRepository Code:
public class SqlRepository<T> : IRepository<T> where T : class
{
DataContext db;
public SqlRepository(DataContext db)
{
this.db = db;
}
#region IRepository<T> Members
public IQueryable<T> Query
{
get { return db.GetTable<T>(); }
}
public List<T> FetchAll()
{
return Query.ToList();
}
public void Add(T entity)
{
db.GetTable<T>().InsertOnSubmit(entity);
}
public void Delete(T entity)
{
db.GetTable<T>().DeleteOnSubmit(entity);
}
public void Save()
{
db.SubmitChanges();
}
#endregion
}
The two methods for adding and deleting UserCourses are:
Service Methods for Adding and Deleting UserCourses:
public void AddUserCourse(int courseId)
{
UserCourse uc = new UserCourse();
uc.IdCourse = courseId;
uc.IdUser = UserId;
uc.DateCreated = DateTime.Now;
uc.DateAmended = DateTime.Now;
uc.Role = "Pupil";
uc.CourseNotes = string.Empty;
uc.ActiveStepIndex = 0;
UserCoursesRepository.Add(uc);
UserCoursesRepository.Save();
}
public void DeleteUserCourse(int courseId)
{
var uc = (UserCoursesRepository.Query.Where(x => x.IdUser == UserId && x.IdCourse == courseId)).Single();
UserCoursesRepository.Delete(uc);
UserCoursesRepository.Save();
}
Ajax
I am using Ajax via Ajax.BeginForm
I don't think that is relevant.
ASP.NET MVC 3
I am using mvc3, but don't think that is relevant: the errors are related to model code.

The problem only occurs intermitently,
for example, adding a row then
deleting it. If I stop the dev server
and restart, the added row is there
and I can delete it no problem.
Your code does not show what the link is between the Added Row and the Delete/Update. Your Add() doesn't return an object reference.
I'm thinking you are missing a Refresh (ie reload the object after Insert). Is your IdCourse also the PK in the Table?

Edit:
Further research has revealed that the problem is with the dependency injection.
The problem was related to how Dependency Injection manages the items it creates. Google for 'lifecycle management' in IoC or DI. Essentially, DI cached a DataContext constructor argument that I injected.
For a way to solve this using the Factory Pattern, see this thread:
Ninject caching an injected DataContext? Lifecycle Management?
The accepted answer solved it all.

Related

MVC 5 Identity 2 - customer UserStore methods not being called

I am trying to implement a custom UserStore for my MVC 5 application so that I can delegate the database commands to my existing database project.
The tables in my database use integer keys, so I created a custom UserManager that inherits UserManager<User, int> instead of just UserManager<User>. For that reason, I also created a custom UserStore that implements IUserPasswordStore<User, int> instead of just IUserPasswordStore<User>.
Briefly:
public class CustomUserManager : UserManager<User, int>
{
public CustomUserManager(CustomUserStore store) : base(store)
{
}
}
public class CustomUserStore : IUserPasswordStore<User, int>
{
private readonly DbContext _db;
public CustomUserStore(DbContext db)
{
_db = db;
}
public Task<User> FindByIdAsync(int userId)
{
return _db.users.SingleOrDefaultAsync(u => u.Id == userId);
}
public Task UpdateAsync(User user)
{
_db.Entry(user).State = System.Data.Entity.EntityState.Modified;
return _db.SaveChangesAsync();
}
}
Now, it seems that when I call UpdateAsync on CustomUserManager, it does not go through my custom CustomUserStore, but rather through some default implementation or something. The problem is evident because CustomUserManager.UpdateAsync() returns Task<IdentityResult>, while my implementation in CustomUserStore returns just Task. Hence there are no errors or anything, but the method is not being called. I think IUserPasswordStore<User, int> should have some method UpdateAsync that returns Task<IdentityResult> but it doesn't...
On the other hand, the FindByIdAsync method does work fine and calls the method in my CustomUserStore.
I am quite sure the problem is due to inheriting the classes with the custom key type (int in my case). Any example of a custom UserStore I can find online just uses the string keys and does not inherit IUserStore<User, int> but just IUserStore<User>.
However I can't figure out my problem. Perhaps I can just override all the methods in my CustomUserManager but that seems like a work-around rather than a solution. Is this a bug in the framework perhaps, I think the custom key types is still relatively new or even in alpha?
I know that this is an old question but I struggled yesterday with the same issue and after some time spent on it, I decided to take a look in the Identity source code and what I've found, almost made me smashed my head against the wall...
Simple, if you call UserManager.UpdateAsync, in the base class you will see that before the UserStore.UpdateAsync there is a validation that takes place, which, in my case, failed (doesn't matter the reason). So, please, be so kind and check in your class (controller class) the result of UpdateAsync which is an IdentityResult and more then sure the Succes result is false.
Evdin

Multiple dependencies in an asp.net mvc controller constructor injected

In my asp.net mvc controller`s constructor I have multiple (5) interfaces which communicate with my database in this way:
[HttpGet]
public ActionResult Create()
{
var releases = _releaseDataProvider.GetReleases();
var templates = _templateDataProvider.GetTemplates();
var createTestplanViewModel = new CreateTestplanViewModel(templates, releases);
return PartialView(createTestplanViewModel);
}
Above I use 2 different interfaces to get data from the database.
business case: To create a testplan I need to show the user the available releases + templates he can choose from.
How can I decrease the dependency/over-injection of these 2 interfaces
In the MVC project:
public class MyController : Controller
{
private readonly IQueryProcessor _queryProcessor;
public MyController(IQueryProcessor queryProcessor)
{
_queryProcessor = queryProcessor;
}
[HttpGet]
public ActionResult Create()
{
var releases = _queryProcessor.Execute(new ProvideReleaseData());
var templates = _queryProcessor.Execute(new ProvideTemplateData());
var createTestplanViewModel = AutoMapper.Mapper
.Map<CreateTestplanViewModel>(releases);
AutoMapper.Mapper.Map(templates, createTestplanViewModel);
return PartialView(createTestplanViewModel);
}
}
You can then constructor inject your current provider implementations into IQueryHandler implementations. The IQueryProcessor is just infrastructure. See this for more info: https://cuttingedge.it/blogs/steven/pivot/entry.php?id=92
Reply to comments:
It's at the site I linked to. Here's mine:
using System.Diagnostics;
using SimpleInjector;
namespace MyApp.Infrastructure
{
sealed class SimpleQueryProcessor : IQueryProcessor
{
private readonly Container _container;
public SimpleQueryProcessor(Container container)
{
_container = container;
}
[DebuggerStepThrough]
public TResult Execute<TResult>(IDefineQuery<TResult> query)
{
var handlerType = typeof(IHandleQueries<,>)
.MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _container.GetInstance(handlerType);
return handler.Handle((dynamic)query);
}
}
}
A good general way to decouple your database would be using a unit of work. Here's a great article on from asp.net, as well as another article on MSDN.
In summary, you create a single unit where all of your database/service calls reside and it can handle the database logic. This would reduce the dependancy of your multiple interfaces into a single point, so you would only need to inject 1 class into your controller.
A quote from the MSDN article:
According to Martin Fowler, the Unit of Work pattern "maintains a list
of objects affected by a business transaction and coordinates the
writing out of changes and the resolution of concurrency problems."
EDIT
It seems to me you basically have these options to reduce constructor dependency count here:
Split the controller
Add layer in front of the two interfaces
Switch to property injection
Service locator
#3 and #4 are included for good measure, but they obviously don't actually decrease the dependency count, they only hide them from the constructor. They also have several disadvantages, and I consider service locator especially evil most of the time.
For #1, if you feel your constructor is actually doing two+ jobs, and there is a clean separation where you could split, I would do so. I assume from your responses that you have already considered this, however, and don't want to do this.
That leaves #2 - adding another layer. In this case that would be introducing a factory interface for that particular view model. Naively, I'll name this ICreateTestplanViewModelFactory, but you can name it something more sensical for your app if you wish. A single method on it would construct a CreateTestplanViewModel.
This makes the fact that the data for this view is coming from 2 sources merely an implementation detail. You would wire up an implementation which takes IReleaseDataProvider and ITemplateDataProvider as constructor dependencies.
This is along the lines of what I was suggesting:
public interface IProvideTestPlanSetupModel
{
CreateTestplanViewModel GetModel();
}
public class TestPlanSetupProvider : IProvideTestPlanSetupModel
{
private readonly IReleaseDataProvider _releaseDataProvider;
private readonly ITemplateDataProvider _templateDataProvider;
public TestPlanSetupProvider(IReleaseDataProvider releaseDataProvider, ITemplateDataProvider templateDataProvider)
{
_releaseDataProvider = releaseDataProvider;
_templateDataProvider = templateDataProvider;
}
public CreateTestplanViewModel GetModel()
{
var releases = _releaseDataProvider.GetReleases();
var templates = _templateDataProvider.GetTemplates();
return new CreateTestplanViewModel(releases, templates);
}
}
public class TestPlanController : Controller
{
private readonly IProvideTestPlanSetupModel _testPlanSetupProvider;
public TestPlanController(IProvideTestPlanSetupModel testPlanSetupProvider)
{
_testPlanSetupProvider = testPlanSetupProvider;
}
[HttpGet]
public ActionResult Create()
{
var createTestplanViewModel = _testPlanSetupProvider.GetModel();
return PartialView(createTestplanViewModel);
}
}
If you don't like constructing a view model anywhere outside the controller, the interface could provide an intermediate object with the same properties that you would copy to the view model. But that is silly, as this combination of data is only relevant for that particular view, which is precisely what the view model is supposed to represent.
On a side note, it seems you are running into pretty common annoyances doing read/write through the same model. Since these issues bother you so, you might investigate CQRS, which perhaps would make you feel less dirty about talking to the database directly for these types of queries and would help you get around the layering labyrinth we all enjoy so much. It seems promising, though I have not yet had the pleasure of test driving it in a production application.

RavenDB and Constructor Injection

In my project, I have the following PageCache entity, which is being stored in RavenDB:
public class PageCache
{
private readonly IHtmlDocumentHelper htmlDocumentHelper;
public string Id { get; set; }
public string Url { get; set; }
public PageCache(IHtmlDocumentHelper htmlDocumentHelper, string url)
{
this.htmlDocumentHelper = htmlDocumentHelper;
this.Url = url;
}
}
I am using Castle Windsor to inject the IHtmlDocumentHelper implementation at runtime. This member is used in methods defined inside the PageCache class, which I stripped from the above snippet for the sake of simplicity.
When I create a PageCache object using the constructor, everything works fine. But elsewhere in my code, I load PageCache objects back from RavenDB:
public PageCache GetByUrl(string url)
{
using (var session = documentStore.OpenSession())
{
return session.Query<PageCache>()
.Where(x => x.Url == url)
.FirstOrDefault();
}
}
My issue is that the objects I get back from RavenDB don't have the htmlDocumentHelper member set, rendering the PageCache methods that depend on it unuseable.
In other words: when I load objects back from documents stored in RavenDB, it won't use my constructor to build the objects, thus not initializing the private members through constructor injection.
Am I doing something wrong here? How would you solve such an issue?
I ended up using the solution proposed by Ayende below. The circular dependency issue I mentioned in the comments only appeared when I registered the DocumentStore in Windsor with UsingFactoryMethod(). The issue strangely disappeared when I used Windsor's DependsOn() and OnCreate() to configure and initialize the DocumentStore directly inside the Register().
My container is now being initialized as follows:
WindsorContainer container = new WindsorContainer();
container.Register(
// Register other classes, such as repositories and services.
// Stripped for the sake of clarity.
// ...
// Register the CustomJsonConverter:
Component.For<CustomJsonConverter>().ImplementedBy<CustomJsonConverter>(),
// The following approach resulted in an exception related to the circular
// dependencies issue:
Component.For<IDocumentStore>().UsingFactoryMethod(() =>
Application.InitializeDatabase(container.Resolve<CustomJsonConverter>()))
// Oddly enough, the following approach worked just fine:
Component.For<IDocumentStore>().ImplementedBy<DocumentStore>()
.DependsOn(new { Url = #"http://localhost:8080" })
.OnCreate(new Action<IDocumentStore>(store =>
store.Conventions.CustomizeJsonSerializer = serializer =>
serializer.Converters.Add(container.Resolve<CustomJsonConverter>())))
.OnCreate(new Action<IDocumentStore>(store =>
store.Initialize()))
.OnDestroy(new Action<IDocumentStore>(store =>
store.Dispose()))
);
Although it seems to be working fine, I feel odd having to call container.Resolve<CustomJsonConverter>() from inside the container.Register() method.
Is this a legal approach to register the dependencies?
Christian,
We can't use your ctor, we don't know what to put in there.
Instead, you can use this technique to tell RavenDB how to create your objects:
http://james.newtonking.com/projects/json/help/CustomCreationConverter.html
Then you can wire this in using documentStore.Conventison.CustomizeSerializer

EF4 Repository Pattern problems injecting repository into service .Cannot seem to get it right

I am finding difficult to test EntityFramework 4 .I am using it using the database first approach,too late now to move to poco.Needed to deliver pretty quickly,no time to learn properly as usual.
I have implemented the repository pattern with unit of work but I am finding difficult to inject a repository into my Service layer so that I can test the behaviour of my business layer service ,validation etc... without hitting the db.
but I am incurring in many little problems.
In order to inject the Repository into the service(constructor) the calling layer need to have a reference to the DAL (EF Entities) . I dont want this
If i have many repositories EG CustomerRepository ,EmployeeRepository than I need to have as many constructors as repositories so that I can inject the repository.
3.Not sure where to go from here. I have not found any example on the net where they inject the repository into the service using EF4. All the examples I have seen they mock the repository on it's own,which is not good to me.
I need to test my service layer/BizLayer without hitting the database.
The all thing is just not testable and adds so many dependencies and problems.
Noddy example I have put together
public class DepartmentServiceLibrary
{
private readonly IDepartmentRepository _departmentRepository;
public DepartmentServiceLibrary(IDepartmentRepository departmentRepository)
{
_departmentRepository = departmentRepository;
}
public List<DepartmentDto> GetDepartments()
{
return DeparmentBiz.GetDepartments();
}
private DeparmentBL _departmentBiz;
private DeparmentBL DeparmentBiz
{
get
{
return _departmentBiz ?? new DeparmentBL(_departmentRepository);
}
}
}
//internal class
internal class DeparmentBL
{
private readonly IDepartmentRepository _departmentRepository;
public DeparmentBL(IDepartmentRepository departmentRepository)
{
_departmentRepository = departmentRepository;
}
public List<DepartmentDto> GetDepartments()
{
using (var ctx = new AdventureWorksContext())
{
var uow = new UnitOfWork(ctx);
_departmentRepository.UnitOfWork = uow;
var query = _departmentRepository.GetAll();
return query.Select(dpt => new DepartmentDto
{
DepartmentId = dpt.DepartmentID,
Name = dpt.Name,
GroupName = dpt.GroupName
}).ToList();
}
}
}
The following TestMethod requires me to add a ref to the dal which defeats the point
[TestMethod]
public void Should_be_able_to_call_get_departments()
{
var mock = new Mock<IDepartmentRepository>();
var expectedResult = new List<Department>(); //Dependency to DAL as Department is a EF Entity generated by EF.
mock.Setup(x => x.GetAll()).Returns(expectedResult);
var companyService = new MyCompanyBL(mock.Object); //InternalVisibileTO
var departments = companyService.GetAll();
//assert removed for brevity
Any suggestions or examples out there that shows how to do it?
thanks
}
The short answer is - since you're not using POCOs, all your layers will have a reference to your DAL.
Without POCOs, you use code generation, which means EF creates the model classes in the Model.edmx.designer.cs file.
An option (haven't tried this - off the top of my head) is to manually project the EF entities into DTOs.
So your Repository might do this:
public List<OrderDTO> GetOrdersForCustomer(int customerId)
{
return _ctx.Orders
.Where(x => x.CustomerId == customerId)
.ToList()
.Select(x => new OrderDTO { // left to right copy });
}
The OrderDTO class could be in a separate assembly, which the repository references, as well as your other projects. So the other projects would work off the DTO assembly, and wouldn't require a reference to the Repository.
But here you're projecting into classes everywhere (basically doing POCO, but manually, and with more work) left to right copying of properties - very painful.
However, that is an option.
Honestly - it does not take long to move to POCOs.
There is a T4 template which will generate the POCOs for you - you could be up and running in a matter of minutes.
And since you're already using dependency injection and repository, you should either bite the bullet and change to POCOs, or keep the reference to the DAL.
Something similar in terms of code can be seen here in GitHub
and detail explanation can be found in TechNet

Error "More than one matching bindings are available" when using Ninject.Web.Mvc 2.0 and ASP.NET MVC 1.0

Recently I've switched to Ninject 2.0 release and started getting the following error:
Error occured: Error activating SomeController
More than one matching bindings are available.
Activation path:
1) Request for SomeController
Suggestions:
1) Ensure that you have defined a binding for SomeController only once.
However, I'm unable to find certain reproduction path. Sometimes it occurs, sometimes it does not.
I'm using NinjectHttpApplication for automatic controllers injection. Controllers are defined in separate assembly:
public class App : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
INinjectModule[] modules = new INinjectModule[] {
new MiscModule(),
new ProvidersModule(),
new RepositoryModule(),
new ServiceModule()
};
return new StandardKernel(modules);
}
protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn("Sample.Mvc");
base.OnApplicationStarted();
}
/* ............. */
}
Maybe someone is familiar with this error.
Any advice?
I finally figured this issue out recently. Apparently, the NinjectHttpApplication.RegisterAllControllersIn() function doesn't do all of the proper bindings needed. It binds your concrete controller implementations to IController requests. For example, if you have a controller class called SampleMvcController, which inherits from System.Web.Mvc.Controller. It would do the following named binding during application start:
kernel.Bind<IController>().To(SampleMvcController).InTransientScope().Named("SampleMvc");
But when debugging the NinjectControllerFactory, I find that request are being made for the Ninject Kernel to return an object for the class "SampleMvcController", not for a concrete implementation of IController, using the named binding of "SampleMvc".
Because of this, when the first web request that involves the SampleMvcController is made, it creates a binding of SampleMvcController to itself. This is not thread safe though. So if you have several web requests being made at once, the bindings can potentially happen more than once, and now you are left with this error for having multiple bindings for the SampleMvcController.
You can verify this by quickly refreshing an MVC URL, right after causing your web application to restart.
The fix:
The simplest way to fix this issue is to create a new NinjectModule for your controller bindings, and to load this module during application start. Within this module, you self bind each of your defined controllers, like so:
class ControllerModule : StandardModule {
public override Load() {
Bind<SampleMvcController>().ToSelf();
Bind<AnotherMvcController>().ToSelf();
}
}
But if you don't mind changing the Ninject source code, you can modify the RegisterAllControllersIn() function to self bind each controller it comes across.
I have been dealing with this problem for months. I tried so many options but was unable to come to a solution. I knew that it was a threading problem because it would only occur when there was a heavy load on my site. Just recently a bug was reported and fixed in the ninject source code that solves this problem.
Here is a reference to the issue. It was fixed in build 2.1.0.70 of the Ninject source. The key change was in KernelBase.cs by removing the line
context.Plan = planner.GetPlan(service);
and replacing it with
lock (planner)
{
context.Plan = planner.GetPlan(service);
}
To use this new build with MVC you will need to get the latest build of Ninject then get the latest build of ninject.web.mvc. Build ninject.web.mvc with the new Ninject build.
I have been using this new build for about a week with a heavy load and no problems. That is the longest it has gone without a problem so I would consider this to be a solution.
Are you sure you really are creating a single completely new Kernel from scratch in your OnApplicationStarted every time it's invoked ? If you're not and you're actually creating it once but potentially running the registration bit twice. Remember that you're not guaranteed to only ever have one App class instantiated ever within a given AppDomain.
My answer was a bit more obvious.
I had declared the binding for one of my controllers more than once during refactor of my code.
I added this to my global.ascx.cs file:
public void RegisterAllControllersInFix(Assembly assembly)
{
RegisterAllControllersInFix(assembly, GetControllerName);
}
public void RegisterAllControllersInFix(Assembly assembly, Func<Type, string> namingConvention)
{
foreach (Type type in assembly.GetExportedTypes().Where(IsController))
Kernel.Bind(type).ToSelf();
}
private static bool IsController(Type type)
{
return typeof(IController).IsAssignableFrom(type) && type.IsPublic && !type.IsAbstract && !type.IsInterface;
}
private static string GetControllerName(Type type)
{
string name = type.Name.ToLowerInvariant();
if (name.EndsWith("controller"))
name = name.Substring(0, name.IndexOf("controller"));
return name;
}
Then called it from my OnApplicationStarted() method as follows:
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
RegisterAllControllersInFix(Assembly.GetExecutingAssembly());
Difficult to know whether this fixed it though because it's so intermittent.

Resources