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;
Related
I have a scenario where I know the primary key of an entity (retrieved from an unrelated source), and I want to update just 1 property (db column). I have NOT already retrieved the entity from the database. If possible I would like to not have to make this extra round trip.
I create the entity using manager.createEntity.
I update one of the properties.
Then set the entityAspect to setModified();
When saving changes, all the properties that were not updated are set to their default values, and the generated SQL UPDATE statement attempts to update all mapped columns.
Is there a way to tell breeze to only generate SQL for specific properties/columns?
thanks
As you discovered, the properties of the originalValuesMap guide the Breeze server's ContextProvider as it prepares the save request. This is documented in the ContextProvider topic.
In your example, you call setModified after you've changed the property. All that does is change the EntityState; it doesn't create an entry in the client entity's entityAspect.originalValuesMap ... therefore the originalValuesMap sent to the server is empty.
I'm a little surprised that the EFContextProvider.SaveChanges prepared an EF update of the entire entity. I would have guessed that it simply ignored the entity all together. I'm making a mental note to investigate that myself. Not saying the behavior is "right" or "wrong".
You do not have to manipulate the originalValuesMap to achieve your goal. Just change the sequence. Try this:
var foo = manager.createEntity('Foo', {
id = targetId
}, breeze.EntityState.Unchanged); // create as if freshly queried
foo.bar = 'new value'; // also sets 'originalValues' and changes the EntityState
manager.saveChanges(); // etc.
Let us know if that does the trick.
i would like to create new entities which use the default values defined in the model.
i've checked the retrieved metadata, and the default values are there:
{"name":"LastName","type":"Edm.String","maxLength":"50","unicode":"true","fixedLength":"false","defaultValue":"admin:
Nachname"},
however they are not taken into consideration when creating a new entity.
This is 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;
My existing table contains nearly 50 columns, most of them have the 'default' constraint.
I have created the model based on this database table. All seemed ok, until i tried to insert a new row. I've got a sql server error stating that some column cannot be null. It appears that creating a model from the database did not preserve the default constraints.
I edited the model manually adding all the defaults and after that inserting didn't fail.
So my question is, how do i create a model that automatically picks up default constraints associated to the columns?
Using mvc4, visual studio 2010, sql server 2008 r2.
Google search didnt make sense as all the people seemed to be talking about something different than what i need.
Pretty sure my answer from Possible to default DateTime field to GETDATE() with Entity Framework Migrations? will work for you too. By using a modified MigrationCodeGenerator class and iterating through the operations list you can update the columns and add DefaultValueSql values based on whatever rules you need.
Well, you have a number of options. You could set the default values in the Model's default constructor. I think this is the better solution.
If you must have the default constraints in your database you could do set defaultValueSql in your data migrations like this:
AddColumn("ExistingTable", "NewColumn",c => c.Int(nullable: false, defaultValueSql: "0"));
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.
I have a Client entity and PostCode entity in Linq to SQL model. The Clients table in database contains client_postcode column which is a FK column to postalcode column in PostCode table, which is a varchar column primary key for PostCode table.
When updating Client, in my code I do this
// postcode
updating.PostCode = (from p in ctx.PostCodes
where p.postalcode.Equals(client.PostCode.postalcode)
select p).First();
where client object is provided from ASP.NET MVC View form. This code seems to set the PostCode related entity fine. But when calling SubmitChanges() I receive the following exception:
Value of member 'postalcode' of an object of type 'PostCode' changed. A member defining the identity of the object cannot be changed. Consider adding a new object with new identity and deleting the existing one instead.
So I am currently unable to change the related entity. How is that done in Linq to Sql?
UPDATE:
After further review and troubleshooting I found out that the problem is in ASP.NET MVC UpdateModel() call. If I call UpdateModel() to update the existing entity with the edited data, something is wrong with the FK assignement for PostCode. If I don't call UpdateModel and do it by hand, it works.
Any ideas what goes wrong in UpdateModel() that it can't set the relationship to foreign key entities correctly?
I am updating this question and starting a bounty. The question is simplified. How to successfully use L2S and UpdateModel() to work when updating items (with related entities as FK) in ASP.NET MVC Edit views?
It seems to me that you are receiving PostCode.postalcode in the http post request.
Based on how model binding works, the UpdateModel call updates .PostCode.postalcode of the model you are passing to it.
Use this overload to include or exclude specific properties.
Wouldn't updating.client_postcode = client.client_postcode; accomplish what you want?
Client.PostCode should be looked up on seek based on client_postocde.
You can not do what you are trying, you cannot change the Postcode like that.
James' idea is in the right direction.
Updatemodel() takes the matching values from the Formcollection
How do these values come in the Formcollection? What are their keys?
basically there are 2 ways in editing an object.
option 1:
all the value names you want to update have corresponding keys in the Formcollection, which leaves you just to call UpdateModel() of the original object. do SubmitChanges()
option 2:
Get the original object, change it's values manually (because the keys dont correspond) and do SubmitChanges()
you are tying to change a link, you cant do that. you can only edit the updating.client_postcode which in this case is a string?
Can you please copy the whole action here? So I can write some code for you without gambling.