Enityframework - ConcurrencyMode where clause - entity-framework-4

Reading up on the web I can set ConcurrencyMode=Fixed against a entity framework database field.
My understanding is that any update statements include in its where clause the original values to determine if the datacontext has changed.
(So if rows effected gets a hit then all is good otherwise we have a conflict )
Now my question is..
Do only the columns changed in the
datacontext get included in the where
clause or all columns that are
marked as fixed.
i.e.
(If I have the following setup)
name=fixedconcurrency
DateofBith=fixedconcurrency
NI=fixedconcurrency
When only the name field changes would I get:
update tbuser set name="newJason"
where Id=2 and name="oldJason" and
DateofBith="19/10/1970" and NI=1234566
or
Update tbuser set name="newJason"
where Id=2 and name="oldJason"
My goal is to only have conflicts raised when a user overwrites another users data ( At field level not record level).
A snippet from MS says that entity framework will only update the fields that a user has edited. IF all fields are included in the where clause it would make this statement redundant.
Thanks,
Jason

All of them. The intention of the feature is for something like a TIMESTAMP field, which the user cannot assign directly.

Related

How to prevent inserting rows with no two rows will have same (duplicates) value

When multiple users are accessing the application,the application should not allow to insert duplicate columns(Eg: Name column in users table where name is unique).
How I am doing this is, in the button click event I am checking whether the name exists in db. this shows validation error if it is exists(duplicate);This works perfectly when single user accessing the app.
But, when 2 users concurrently inserting a row(user) with same column name it is allowing to inserting records with same name, because by the time first user's request hit the db for checking whether the name already exists, second user's record(with duplicate name) is not yet inserted.
so, no validation is showing.
How to fix this issue in nhibernate sessions?.Can I use locking?
please advice.
You should enforce this with a unique constraint on the database. Then when committing your insert transaction you should catch the error of the constraint violation. That's one of the things a database is great at doing.

GORM read only columns

Most of our tables have one or more columns which are set by the database, either by a trigger, or we want to use the database default value (which requires not sending the field at all in the insert or update)
This includes transaction dates set in the dB (so all the times are times stamped very accurately by a single source, not relying on the accuracy of the time on an arbitrary server or pc.)
The second VERY common use case is say if a customer record has his address and a last logged in field. the last logged in field (and number of failed logins) is set by another part of the system (e.g. by a web site server). The current overly simplistic CRUD system which GORM provides would overwrite such a field when an operator or customer edits their address for example. This is because GORM includes in its update and insert statements every field, even if it's null, or if it has not been changed.
We need a way to scrub the field from inserts and updates, but still have it used in the read calls.
I.e. a true "read only" attribute.
We tried this:
failedLogins editable: false, attributes: [readonly:true]
Which has no effect on the SQL generated (and doesn't even affect the scaffolded UIs - its still editable in create and edit, in grails 2.4.4 at least, but thats another story)
When we do want to explicitly write one of these fields, such as number of failed logins, we would resort to using embedded SQL.
I saw this post: Read-Only columns
Which asks exactly the same question, but only gives one solution, which is this plugin:
extended GORM mappings
Unfortunately, this plugin has not been updated since 2010, and only works with 1.3. We need something which works with 2.4.4.
Any grails app which has multiple systems which edits independent fields needs something like this, or to do extensive locking (Which is usually out of the question).
E.g. an operator opens the customer details for editing, edits something editable (e.g. address), then the operator fails a login on the website (a different grails or non-grails app), then the operator saves the player details. If the saving included the numberOfFailedLogins field, the system would fail. If opening the player details for editing locked the player, then the player would not be able to login, as updating the "lastLoggedIn" or "numFailedLogins" would fail to be able to write due to the lock. The solution is VERY simple - read only columns. Another way would be to put each read only type field in their own tables, but this would be untenable (and result in hundreds of one field tables)
Or we go back to using MyBatis, which has no such issues, and full control. Sadly, there is no good mybatis plugin for grails.
You can use derived properties for string and number properties:
class Batch {
String name
Integer timesRun
static mapping = {
timesRun formula: 'times_run' //times_run is a column in the "batch" table
}
}
In the code above, timesRun would be read in from the database but ignored in inserts and updates as Hibernate considers the column a calculated one.
Updated the example because the original one may have been misleading
This probably doesn't specifically answer your question, but you can use dynamicUpdates to tell GORM to only update the properties of the domain object that have changed during the current session. So as long as you don't change the "read-only" property in your code it won't be set in the SQL update statement generated by Grails. For added safety you could override (and noop) the setter so that your code can never change that property.
https://grails.github.io/grails-doc/latest/ref/Database%20Mapping/dynamicUpdate.html
One of the downsides of dynamicUpdates is that it might make the Hibernate query cache less useful. However, it seems that some Grails/Hibernate experts recommend that you disable the query cache anyway (at least in older versions of Grails). Not sure if that's true of Grails 2.4+
http://grails.github.io/grails-howtos/en/performanceTuning.html
http://www.anyware.co.uk/2005/2012/11/12/the-false-optimism-of-gorm-and-hibernate/
http://tech.puredanger.com/2009/07/10/hibernate-query-cache/

How does Breeze handle database column defaults?

I can't find any info about this in the documentation, so I will ask here. How does breeze handle database column defaults? I have required columns in my database, but there are also default static values supplied for these in the database column definitions. Normally, I can insert null into these columns, and the new records will get the default. However, breeze doesn't seem to be aware of database column defaults, and the entities that have null in these columns fail validation on saving.
Thanks,
Mathias
Try editing the edmx xml by adding StoreGeneratedPattern = "Computed" attribute to the column with default value in the DB.
Edit:
Actually, before doing editing the xml, try setting the StoreGeneratedPattern property to Computed in the model editor itself.
Update:
This was fixed in Breeze 1.4.6 ( or later), available now.
Original Post:
There is currently in a bug in Breeze that should be fixed in the next release, out in about week. When this fix gets in then breeze will honor any defaultValues it finds in the EntityFramework data model.
One problem though is while it is easy to get 'defaultValues' into a Model First Entity Framework model via the properties editor, it's actually difficult to get it into a Code First EF model, unless you use fluent configuration. Unfortunately, EF ignores the [DefaultValue] attribute when constructing Code First model metadata.
One workaround that you can use now is to poke the 'defaultValue' directly onto any dataProperty. Something like:
var customerType = myEntityManager.metadataStore.getEntityType("Customer");
var fooProperty = customerType.getProperty("foo");
fooProperty.defaultValue = 123;

Entity Framework complaining about required fields when saveChanges even if valid data are setted

I'm using Entity Framework (DbContext with database first) with MVC. When user save from a form, I have a condition in the controller that send the entity to the update of insert method depending of some internal flag of mine.
When sending entity to the update method, I flag it to modified using context.Entry(myEntity).State = EntityState.Modified;, I call saveChanges() and everything work well.
When sending the entity to the insert method, I flag it to added using context.Entry(myEntity).State = EntityState.Added; but when calling saveChanges() I receive error about 2 fields that are required...
The problem is that thoses 2 fields are not empty and they effectively contain valid data just before saving... I have even try to force new values to thoses 2 fields just before saving but same error.
It may be usefull to mention that I'm using Devart DotConnect For PostgreSQL as db provider.
Any idea how to debug this problem?
EDIT:
Here is the error:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
When looking for this EntityValidationErrors I receive the 2 following specific errors:
The flg_actif field is required
The user_creation field is required
As mentionned before, those fields are filled with data just before saving so I don't understand what is happening.
I'm using EF v4.0.30319 (system.data.entity=> v4.0 and EntityFramework=> v4.4)
EDIT2:
Just to clarify a little bit more: The entity I'm trying to insert already exist in database. The form show the data of this database row. When saving, I decide if I update the row (this work well) but sometime, I need to insert the edited row as a new register instead of updating it to keep an history of the change in database.
Could you verify if the EntityKey property is set or null on the items you are trying to save?
If it already has a key, the context is already aware of the item, and you should use Attach instead of setting the state to added manually.
EDIT: To summarise the point from below. It looks like what you are doing is inserting a new copy of a row already associated with a context. That is almost certainly your problem. Try creating a fresh object based on your original row (i.e. copy the variable values or use a copy constructor), then add that new object.
Additionally, you should not need to set the state manually on a newly added object. You are trying to force the state here because the context doesn't see that item as a new one.

NHibernate - Updating only specified object properties identified at runtime

I'm trying to implement a very granular security module in an ASP.NET MVC 3 app where only certain users can edit certain columns on records in a table. I can imagine that the update SQL statement's list of columns would only include the columns that the user had the right to change. The thing is, I'm planning to use an ORM like NHibernate. I'm wondering if NHibernate provides a way to determine at runtime which properties of a model should be part of an Update. Or is my only option to, on the POST method, get the model again from the database, set only the properties that the user is allowed to set then finally Save the model. Also, is this a good way to handle my requirement of of granular security?
Would dynamic-update and dynamic-insert be enough?
dynamic-update (optional, defaults to false): Specifies that UPDATE SQL should be generated at runtime and contain only those columns whose values have changed.
dynamic-insert (optional, defaults to false): Specifies that INSERT SQL should be generated at runtime and contain only the columns whose values are not null.
Otherwise it might be possible with events or interceptors, but I've never used them so I don't know exactly.

Resources