I have a breeze Entity that has a data property that is a complex object itself. when creating the entity breeze creates a complex object with the default values for that property. I want to make it null, is it posible????
Thanks in advance!!!
Tony
No, a complex property cannot be null, because it is conceptually a value type. We also wanted to make sure that you could always navigation thru a complex type. i.e. that you never have to worry about null checking a complex property path. For example: aCompany.Address.City where the 'Address' property is a complex type will never throw an exception because 'Address' can never be null.
What you can do is set all of the properties within a complex type to null ( or default values), and write logic to handle a complex object that matches these characteristics.
Hope this makes sense.
Related
I have a case where a breeze entity loses it's originalValues for unmapped properties when that entity is fetched a second time.
I know why this is happening I just don't think it should.
The originalValues are being cleared on the subsequent fetch because breeze sees that the entity is not modified and correctly merges in the incoming values from the server. However, my entity has unmapped properties that have changed and whose original values are stored in the originalValues hash. These are being cleared.
I can understand an argument that says this should be the behaviour with a MergeStrategy set to OverwriteChanges.
However, this clearing of originalValues occurs with a MergeStrategy of PreserveChanges. That behaviour I do not think is a good idea.
With a MergeStrategy of PreserveChanges, when an entity is considered unmodifed, etc, and the incoming values are merged in I do not think originalValues should be cleared.
Now there is a possible workaround by setting using a MergeStrategy of SkipMerge, however this causes problems as the entity is then never refreshed with incoming values.
So can this be behaviour be changed please?
Thanks
Christian
A very interesting use case ... one worth some serious reflection.
Let's walk through the semantics of merging query results when the MergeStrategy is "PreserveChanges".
First, some observations:
Breeze does not change the EntityState when you change an unmapped property
Breeze DOES preserve the pre-change value of an unmapped property in OriginalValues.
Let's consider how Breeze merges query results:
when the EntityState is in a changed state, all properties (mapped and unmapped) are preserved even if a corresponding queried property value is different.
when the EntityState is "Unchanged", all properties (mapped and unmapped) are replaced by corresponding queried property values discovered in the query results payload.
Breeze does not support a partial merge. It will not overwrite some properties and preserve others.
I don't know for certain why query processing clears OriginalValues (I say that without having looked into it yet or even confirmed that it does). But I think it is doing the right thing.
Consider what it means when any property is merged into an unchanged entity. Suppose property foo was 1 before the query and the new queried value is 2.
Subsequently, we set foo to 3. What should the the "original value" be at that time? It should be 2, right? It shouldn't be 1. It should be the last value retrieved from the server.
It follows that after a merge, original values are implicitly identical to the entity's most current values. That is, if a property had a value in OriginalValues, it should be identical to the corresponding current value. And if the current value === the original value, we might as well remove that property from the OriginalValues ... which means clearing the OriginalValues for that property is harmless.
Because Breeze performs full merges (not partial merges), it follows that clearing the entire OriginalValues is consistent behavior.
According to this line of reasoning - if you believe that mapped and unmapped properties should follow the same merge rules - Breeze is doing exactly the right thing.
Perhaps what you want is to treat a change to an unmapped property as a change to the EntityState.
I think we did that at one time in the past but we were persuaded that the EntityState should only reflect changes to mapped properties which are presumed to be the persisted properties.
It appears that you disagree, at least in your specific use case. I think (please confirm) that when you change an unmapped property, you want Breeze to treat the entity as "dirty".
Fortunately, you can handle this yourself. Add a handler to the EntityManager.entityChanged event and change the EntityState when something updates an unmapped property. You can do this broadly or selectively.
You'll have an uphill climb if you really seek different treatment of mapped and unmapped properties. We'll listen of course ... but you'll have to make one heck of a great argument.
You might get further by proposing something more general purpose such as a new MergeStrategy that supports a developer-defined custom policy.
Maybe we'd extend the metadata such that you can specify a merge function that governs how Breeze merges properties for a given EntityType. That would be cool.
It would be a significant new feature, requiring a ton of testing. I think it's going to take a lot of persuading to get that one on the board.
I have a core data model with a Transformable attribute called location. However, when I create a new entity with initWithEntity:insertIntoManagedObjectContext:, location is nil.
Is that the expected behavior? I was expecting all the memory for a field in an entity to be allocated upfront. If this is the expected behavior, what is the recommended way to work around this? Is allocating memory for location in awakeFromInsert a good idea?
Yes, that is expected. If you haven't given the entity any data how would it know what size to allocate. Even then, what would it do with that allocation because it isn't a real object and you can't really convert it into one. You should expect the property to hold nil if there is nothing there. You do no need to and should not want to fill it with some default empty allocation.
If you have a default object that you want to set then that's a different matter. Then awakeFromInsert could be a good option. The question is whether the default object should be saved into the store (and therefore be searchable). If not you might want to implement a custom accessor method to return your default object if the stored value is nil.
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.
In my understanding, the ViewModel pattern was designed to pass all the relevant data to View because 1) the view shouldn't perform any data retrieval or application logic and 2) it enables type-safety, compile-time checking, and editor intellisense within view templates.
Since dynamic expressions are defined at runtime, does this mean we don't get any of the 2)'s goodies?
You do not lose any of the existing functionality. You can still have a strongly-typed view such that when you access the Model property it will be of your specified type. The only thing that is added is a shorter way of accessing items in the ViewData dictionary.
Instead of the following
ViewData["MyData"]
you can have
View.MyData
Notice that you do not lose any type-safety because you never really had any. In the former case the key is a string (no certainty that it exists in the dictionary) and the value is an object so unless you cast it you can't do that much with it. In the latter you also get no intellisense and the returned value must be cast to something useful.
In fact the implementation of View.MyData simply takes the property name ("MyData") and returns the value coming from the ViewData dictionary.
Arguably the one thing you lose is the ability to have spaces or other characters that are not legal C# identifiers in your key names.
PLEASE NOTE: I've answered my own question with a link to an answer to a similar question. I'll accept that answer once I'm allowed to (unless anyone comes up with a better answer meantime).
I have a database column defined as NVARCHAR(1000) NOT NULL DEFAULT(N'') - in other words, a non-nullable text column with a default value of blank.
I have a model class generated by the Linq-to-SQL Classes designer, which correctly identifies the property as not nullable.
I have a TextAreaFor in my view for that property. I'm using UpdateModel in my controller to fetch the value from the form and populate the model object.
If I view the web page and leave the text area blank, UpdateModel insists on setting the property to NULL instead of empty string. (Even if I set the value to blank in code prior to calling UpdateModel, it still overwrites that with NULL). Which, of course, causes the subsequent database update to fail.
I could check all such properties for NULL after calling UpdateModel, but that seems ridiculous - surely there must be a better way?
Please don't tell me I need a custom model binder for such a simple scenario...!
Might be duplicate or something in the line of this:
MVC binding form data problem
I fear custom model binder will be necessary. ;)
You might want to use a partial class implementation of your entity that implements the on property changed handler for that particular property. When you detect that the property has been changed to NULL, simply change it to string.Empty. That way anytime NULL is assigned to the property it gets reset to the empty string.