How to override EFContextProvider to create a read only OData entity - breeze

So I'm pretty sure I'm on the right track, just need some help implementing this the way I want to. So to accomplish this readonly entity, I know I need to subclass the EFContextProvider and override a method. I know I can accomplish this by overriding SaveChanges, but I'm wondering if I should override the Dictionary property instead, leaving the readonly property out of that Dictionary. Will this effect anything? If so, what will it effect?

I assume you have client logic that prevents it from attempting to save changes to a "read-only" entity. That leaves guarding the server which should reject any request that attempts to save a "read-only" entity, right?
If so, I would put logic in the EFContextProvider.beforeSaveEntity that tests if the entity is savable and throws if it is not. I often make my entities inherit from ISaveable (my interface) and throw an exception when I see an entity that is not.

Related

typo3 flow isDirty on model

Im trying to find out which attributes of an entity have been changed.
As far I have seen, there is a PersistenceSession with a method to check an object if an attribute isDirty. But its always true because it never registers the old object.
So if I take the demo from the QuickGuide and override the update method in the CoffeeBeanRepository:
/**
* #param \Acme\Demo\Domain\Model\CoffeeBean $coffeeBean
*/
public function update($coffeeBean) {
\TYPO3\Flow\var_dump($this->persistenceSession->isDirty($coffeeBean, 'name'), "name changed before");
parent::update($coffeeBean);
\TYPO3\Flow\var_dump($this->persistenceSession->isDirty($coffeeBean, 'name'), "name changed after");
}
... its always TRUE (both), despite I didn't change anything.
Anyone an idea/reference how this can be accomplished?
I am using it for a REST API where a user can't update several fields and on editing of some fields additional actions have to be executed.
The persistenceSession is part of the generic persistence backend of Flow and is neither maintained, nor really used unless you explicitly deactivate doctrine. Hence persistenceSession will not help you, because all entities are considered new for the persistenceSession as you noticed.
With doctrine you need to get the entity changeset from the "UnitOfWork", which you can get from an injected \Doctrine\Common\Persistence\ObjectManager. See also Is there a built-in way to get all of the changed/updated fields in a Doctrine 2 entity
However, this is a suboptimal solution and a hacky work-around at best. If you need to track changes to your entity, it should be an explicit part of your domain model. For example make your setters record a changed properties list, when the given value is different from the current.
When done, you could even optimize doctrines change tracking on the way with that: http://doctrine-orm.readthedocs.org/en/latest/reference/change-tracking-policies.html#notify

Entity Framework 4: ObjectContext event on successful save

Is there a good way to detect when the ObjectContext changes are actually committed?
SavingChanges occurs before going to the data store but I also need a way to know if those changes where actually committed.
Thanks in advance
John
Update:
What I have is a code first DbContext. This is fed into dynamic data which as I discovered uses the DbContext's internal ObjectContext (to which I have access when casting to IObjectContextAdapter). The dbcontext's SaveChanges is not called, the objectcontext's SaveChanges is used instead. All I want to do is to be notified after the save is complete (i.e. event SavedChanges) so I can invalidate my cache.
There is no build-in event to handle this but you can override SaveChanges method in your derived context and fire any custom event specific to your own context type after you call base.SaveChanges.
pardon me, but I can't find the solution in the answer.
Let me rephrase this question according to my understanding (and my case):
I am using Dynamic Data, which ONLY accepts ObjectContext as configuration; if you use DbContext (which is the way to go with Code First) then you will have to pass the property "IObjectContextAdapater.ObjectContext" like the following:
DefaultModel.RegisterContext(() => { return ((IObjectContextAdapter) new MyDbContext()).ObjectContext; }, new ContextConfiguration() { ScaffoldAllTables = true });
The problem here is that when you save changes, the SaveChanges method of the MyDbContext is NOT called, instead Dynamic Data calls the method SaveChanges in the MyDbContext.ObjectContext.
So overriding the SaveChanges in MyDbContext is useless in this case.
How can we access the SaveChanges in the ObjectContext property and change the behavior so we can write our custom code?
But anyway, the solution I found correct was in a comment by "rene" to the question above, which is adding an event handler for SavingChanges EVENT in the ObjectContext property, here is the link again:
http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.savingchanges.aspx
I hope this clears it

Introduce custom property in OData

In my database User table I have DataTime field called DateDeleted - which is null while user exists and is set to the proper value when user "is deleted".
I wonder if there is a way to introduce IsDeleted property for User entity so that
http://odata/service.svc/Users(1)/IsDeleted
will return true or false depending on whether DateDeleted is set or not
My research in google hasn't got any results and I am almost sure it is not possible to implement through odata. Am I right?
With the built in providers this is not possible on the WCF DS side of things. You might be able to somehow do this on the EF side (expose it as a property of the EF entity), but I'm not sure if that's possible.
On the WCF DS side, you would have to implement a custom provider in order to do this. Which may be quite a lot of work unfortunately. If you're interested see this for starters: http://blogs.msdn.com/b/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx.
What Shawn refers to above is a method on the custom provider interface.
You can specify the value you want by implementing the method DataServiceQueryProvider.GetPropertyValue.
Please find the reference here:
http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicequeryprovider.getpropertyvalue.aspx
The method takes two parameters, the entity object (a User instance) and the resource property (in this case "IsDeleted"). You can try to get the property value of "DataDeleted" from the entity object, and return the value of "IsDeleted" as you want.

AutoMapper custom type converter dependencies

I am trying to implement Automapper to map a ViewModel to an Entity where one of the properties of the Entity is also an Entity.
I want my converter to use NHibernate's ISession.Load<> method to load this.
So the question is what is the best way of injecting ISession into my ITypeConverter implementation? Also one thing to keep in mind is that ISession that gets injected will be disposed off, so I would need to inject a new ISession everytime when a mapping needs to happen?
We do this in our systems, and have things like Guid->Entity type converters. However, we scope our ISessions per HttpContext, so a new ISession will not be injected per ITypeConverter. However, AutoMapper does instantiate a new ITypeConverter instance every time it's needed.
But two entities coming together from different ISession instances will lead into trouble. Just make sure you share a single ISession instance per HttpContext, and you'll be set.
I don't know about nHibernate sorry and no one seems to want to answer this question so...
The way I would tackle this is to maybe write my own Custom Model Binder. It can then be resonsible for mapping my ViewModel to my Entity.
You will also have access to the HttpRequest object so you can get all your text fields out and map them to your entity.
I hope this helps even though it's not specific to your question.

Updating a disconnected LINQ object with MVC Framework RC1

This is a little out there but I have a customer object coming back to my controller. I want to just reconnect this object back to the database, is it even possible? I know there is a datacontext.customers.insertonsubmit(customer), but is there the equivalent datacontext.customers.updateonsubmit(customer)???
This is what I don't like about LINQ-to-SQL.
It generally works fine if you're querying and updating in the same scope, but if you get an object, cache it, and then try to update it later, you can't.
Here's what the documentation says:
Use the Attach methods with entities that have been created in one DataContext, and serialized to a client, and then deserialized back with the intention to perform an update or delete operation. Because the new DataContext has no way of tracking what the original values were for a disconnected entity, the client is responsible for supplying those values. In this version of Attach, the entity is assumed to be in its original value state. After calling this method, you can then update its fields, for example with additional data sent from the client.
Do not try to Attach an entity that has not been detached through serialization. Entities that have not been serialized still maintain associations with deferred loaders that can cause unexpected results if the entity becomes tracked by a second data context.
A little ambiguous IMHO, specifically about exactly what it means by "serialized" and "deserialized".
Also, interestingly enough, here's what it says about the DataContext object:
In general, a DataContext instance is
designed to last for one "unit of
work" however your application defines
that term. A DataContext is
lightweight and is not expensive to
create. A typical LINQ to SQL
application creates DataContext
instances at method scope or as a
member of short-lived classes that
represent a logical set of related
database operations.
So, DataContexts are intended to be tightly scoped - and yet to use Attach(), you have to use the same DataContext that queried the object. I'm assuming/hoping we're all completely misunderstanding what Attach() is really intended to be used for.
What I've had to do in situations like this is re-query the object I needed to update to get a fresh copy, and then do the update.
The customer that you post from the form will not have entity keys so may not attach well, also you may not have every field of the customer available on the form so all of it's fields may not be set.
I would recommend using the TryUpdateModel method, in your action you'll have to get the customer from the database again and update it with the form's post variables.
public ActionResult MySaveAction(int id, FormCollection form)
{
Customer updateCustomer = _Repository.GetCustomer(id);
TryUpdateModel(updateCustomer, "Customer", form);
_Repository.Save(updateCustomer);
}
You will have to add in all your own exception handling and validation of course, but that's the general idea.
You want to use the attach method on the customers table on the data context.
datacontext.customers.Attach(customer);
to reconnect it to the data context. Then you can use SubmitChanges() to update the values in the database.
EDIT: This only works with entities that have been detached from the original data context through serialization. If you don't mind the extra call to the database, you can use the idiomatic method in ASP.NET MVC of retrieving the object again and applying your changes via UpdateModel or TryUpdateModel as #Odd suggests.

Resources