Going from the example given here...
http://ericswann.org/blog/archive/2009/04/06/linq-to-sql-datacontext-provider-revisited.aspx
I'm trying to use the datacontext between the MembershipProvider and the RoleProvider.
For instance, when I call Membership.GetUser(XXXXXX) in the RoleProvider, I get an error because it pulls an item from one datacontext and tries to use it (hence the need for the repository)
But I am ...really stupid, and this is some pretty advanced stuff. Seeing as how I do not get to 'instantiate' the Providers, does anyone have an idea how I might go about using this?
First of all pick your datacontext caching strategy. Use DataContextThreadCache if you're working in winforms, where the context is cached in your running thread context. Use DataContextWebCache if you're working with web apps where the context is cached in HTTP run-time cache.
To register your datacontext look at DataContextProvider.RegisterDataContext and its overloads. Here is an example:
DataContextProvider.RegisterDataContext<YourDataContextType, YourCacheStrategyType>(contextKey, contextConnectionString)
contextKey: is the key you will use to retrieve your data context with.
contextConnectionString: is the connection string for your data context.
This call will use the type of DataContext you specified to create an new instance of it. It will then cache it using the specific caching strategy you specified also. This should probably be called somewhere during the initialization phase of your application. Your repository can then use GetDataContext as outlined in that blog post to get the context instance.
Related
The objective of the method below is to delete the data from the database using entity framework. I am populating the subscriptions entity by passing two parameters and then calling the atttach and remove method of the context class. Bureau entities is the context class.
using (BUREAUEntities bureauEntities = new BUREAUEntities())
{
var subscription = new SubcriptionRepository().GetSusbcriptionBySubscriptionTypeId(subscriptionTypeId, companyId);
bureauEntities.Subscriptions.Attach((DataAccessLayer.DatabaseModel.Subscription)subscription);
bureauEntities.Subscriptions.Remove(subscription);
bureauEntities.SaveChanges();
}
I am getting the following error message at An entity object cannot be referenced by multiple instances of IEntityChangeTracker at line
bureauEntities.Subscriptions.Attach((DataAccessLayer.DatabaseModel.Subscription)subscription);
Could somebody tell me where am I going wrong ?
Generally, the error means that you retrieved subscription from one instance of your BUREAUEntities context, while you're trying to remove it from another instance. The cure is to simply be smart about instantiating your context, and it's easy to fall down on that front when using using, since it disposes of the instance as soon as the block exits.
Essentially, make sure all your code that will interact with your context is within the same using block. Even better, use a DI (dependency injection) container like Ninject or Unity to create a context scoped to the request. Then you never have to worry about ending up with multiple copies of the same context floating around.
I have recently changed from ObjectContext to DbContext using EntityFramwework by upgrading to EF6
Most stuff works, but saving and updating won't. Here is an example:
public void AssignToAdmin(Product product, Admin admin)
{
var pcsps = from s in context.ProductCreationSections
join pcsp in context.ProductCreationSectionAndProducts on s.ProductCreationSecitionID equals pcsp.ProductCreationSectionID
where pcsp.ProductID == product.ProductID && s.IsManagerAssigned
select pcsp;
foreach (var pcsp in pcsps.Include("AssignedAdmins"))
{
pcsp.AssignedAdmins.Add(admin);
}
}
Trying to execute the line pcsp.AssignedAdmins.Add(admin), I get the error:
Error: The relationship between the two objects cannot be defined
because they are attached to different ObjectContext objects.
There is one context for the class and it comes from Dependency Injection (the class is a Service in an MVC app).
I've tried removing/attaching and so on, but this doesn't fix it - it just gives different error messages. It's not even obvious which entity is using another context.
Any ideas of where this other context the error message refers to is coming from?
See The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects
Where has admin come from?
Getting the admin object from the same context as the pcsp object should help.
Sorted it, but it was quite a major refactor.
The issue was that each service received it's own instance of 'context', so when two entities from two services were expected to work together, they wouldn't as each belonged to a different context.
One solution would have been to make the class that created the context a 'Singleton' so that it always returned the same instance, but that would have been very BAD as every page would then use the same context.
Each service got it's own instance of 'context' through Dependency Injection.
I changed the project so only the controllers got an instance of context through DI. Then, in the controller constructor, this context was passed to the services that the controller had received through dependency injection.
This way, each request only ever uses a single instance of context, but this instance is still short lived, as it is supposed to be as each request has its own context and doesn't share one.
Not sure this is the way it is supposed to work, but given the web app I was working with, this seemed to be the best solution.
I also had to go through and add a 'context.SaveChanges();' statement everywhere a change to the database was made.
Not sure why this should be when the old version of EF did this automatically, but it now works.
Thanks for the advice Derrick
I was skimming some of the Grails documentation and found this bit about the read() method in Grails. If I'm understanding this correctly, you can pull a "read-only" version of an object from the database that will only be saved on an explicit save() call. It seems to me then, that you should use a read() call whenever you have an object that you don't expect to be changed.
But why wouldn't you just always use a read() call? Since the object will be changed to read/write permissions if you save() it anyway, wouldn't it be safer to just read in the object instead of getting it?
You're probably correct - it'd be equivalent in most cases. But Hibernate doesn't require that you call save() since it does dirty checking during a flush and since Grails uses an "Open Session in View" interceptor there will always be a flush at the end of each request. This surprises people who make changes in an instance retrieved by get() that were meant to only be temporary while rendering the view but then the changes get persisted anyway without a save() call. read() would make more sense in that scenario.
One performance optimization is to use http://grails.org/doc/latest/ref/Database%20Mapping/dynamicUpdate.html to only push changed fields to the database. The default is to push all fields whether they're changed or not since then there's no need to generate new SQL for each update. If you read() an instance Hibernate doesn't keep the original data so dynamic update wouldn't be possible since there would be no way to know which fields are dirty.
A week back, I had an ASP.NET MVC application that called on a logical POCO service layer to perform business logic against entities. One approach I commonly used was to use AutoMapper to map a populated viewmodel to an entity and call update on the entity (pseudo code below).
MyEntity myEntity = myService.GetEntity(param);
Mapper.CreateMap<MyEntityVM, MyEntity>();
Mapper.Map(myEntityVM, myEntity);
this.myService.UpdateEntity(myEntity);
The update call would take an instance of the entity and, through a repository, call NHibernate's Update method on the entity.
Well, I recently changed my logical service layer into WCF Web Services. I've noticed that the link NHibernate makes with an entity is now lost when the entity is sent from the service layer to my application. When I try to operate against the entity in the update method, things are in NHibernate's session that shouldn't be and vice-versa - it fails complaining about nulls on child identifiers and such.
So my question...
What can I do to efficiently take input from my populated viewmodel and ultimately end up modifying the object through NHibernate?
Is there a quick fix that I can apply with NHibernate?
Should I take a different approach in conveying the changes from the application to the service layer?
EDIT:
The best approach I can think of right now, is to create a new entity and map from the view model to the new entity (including the identifier). I would pass that to the service layer where it would retrieve the entity using the repository, map the changes using AutoMapper, and call the repository's update method. I will be mapping twice, but it might work (although I'll have to exclude a bunch of properties/children in the second mapping).
No quick fix. You've run into the change tracking over the wire issue. AFAIK NHibernate has no native way to handle this.
These may help:
https://forum.hibernate.org/viewtopic.php?f=25&t=989106
http://lunaverse.wordpress.com/2007/05/09/remoting-using-wcf-and-nhibernate/
In a nutshell your two options are to adjust your service to send state change information over the Nhibernate can read or load the objects, apply the changes and then save in your service layer.
Don't be afraid of doing a select before an update inside your service. This is good practice anyway to prevent concurrency issues.
I don't know if this is the best approach, but I wanted to pass along information on a quick fix with NHibernate.
From NHibernate.xml...
<member name="M:NHibernate.ISession.SaveOrUpdateCopy(System.Object)">
<summary>
Copy the state of the given object onto the persistent object with the same
identifier. If there is no persistent instance currently associated with
the session, it will be loaded. Return the persistent instance. If the
given instance is unsaved or does not exist in the database, save it and
return it as a newly persistent instance. Otherwise, the given instance
does not become associated with the session.
</summary>
<param name="obj">a transient instance with state to be copied</param>
<returns>an updated persistent instance</returns>
</member>
It's working although I haven't had time to examine the database calls to see if it's doing exactly what I expect it to do.
I've created a object that I'd like to have accessible from wherever the request-object is accessible, and to "die" with the request, more or less like how you always in a mvc-application has access to the RouteData-collection. Especially it's important that I have access to this object in the execution of action-filters. And also there need to be created a new object of my class whenever a new request is made to the page (the object needs to be request-safe, ie. only one request modifies that one object).
Any thoughts about how to achieve this?
HttpContext is a good place for this. The Items dictionary could be used to store objects relative to the request.