Entity Framework turn off caching - c#-4.0

I am trying to figure out how to turn off caching of the DbContext using the repository pattern. Right now my view and CRUD functions use the same context, so putting .AsNoTracking() on the DbSet is not working because updating the data is not happening as it did before.
_context.Entry(e).State = e.Id == 0 ? EntityState.Added : EntityState.Modified;
_context.SaveChanges();
Can someone explain caching in EntityFramework, so that I can provide dynamic functionality where if a user updates a record and then they click a link to view other data, then the data represented on the new grid takes in to effect the change from the previous controller action...hope that makes since.
View Orders -> Update Order -> Save Order -> View Users -> View correctly shows Item count aggregate based off of order changes.

Question you are asking is not really easy.
what you would do depends on what type of entities you are using
as you probably know there are several generic options - EF entities, Self Tracking entities, POCO no proxy, POCO with proxy
depending on what you have you would either
1) reattach entity, call Load on navigation property of entity
2) reattach entity, call LoadProperty on context
3) just call either Load / LoadProperty if the context remain the same
What you refer as caching in fact is entity tracking , so you can turn it off either detaching entities or setting MergeOption to MergeOption.NoTracking on ObjectQuery

Related

How to create and update with the same form

I use the repositoryFactory in a custom plugin's Vue file in Shopware 6. When I save an entity I do this:
this.settingsRepository
.save(this.setting, Shopware.Context.api)
.then((result) => {
In case the person sends the form and this function is called, I want to get back the id of the setting in case the person hit's the save button again. But then the entity needs to be updated and not created. As I see from the response, there is an id, but it's in config.data -> json serialised.
How's the default way of solving this issue?
The best practice would be to re-fetch the entity after persisting it. This is because some entities may have fields that get automatically computed or indexed server-side and you'd probably always want to have the entity in its actual current state. If you're absolutely sure you don't want to fetch the entity again, you could manually set the _isNew flag to false after persisting:
this.setting._isNew = false;
This will then cause the save function to use the update instead of the create route. Keep in mind that this is actually kind of an internal property, as there is no setter for it and as already mentioned fetching the entity again is encouraged.
Also you shouldn't have to worry about the id. It should've already been generated client-side and set to the entity, when using the repository to create a new entity like that:
this.setting = this.settingsRepository.create();

Automapper to update an existing object as opposed to creating a new one [duplicate]

This question already has answers here:
Automapper: Update property values without creating a new object
(4 answers)
Closed 4 years ago.
Is there any way to use Automapper 5.1.1 to update an existing object as opposed to creating a new one.
For example we have a Customer entity and a CustomerViewModel. We would like to update an existing Customer with the CustomerViewModel field values.
Would greatly appreciate your assistance.
It is not adviced to use Automapper to map a model to your Entity. Dependencies or Informations can be overwritten if it isn't used wisely.
But to use it as you want, you only need to create a map from your Model to your Entity and then call
Mapper.Map(myModel, myEntity);
The mapping to entity Problem
I guess you use a ORM like NHibernate or EF, then your Entites are Proxies, where references are proxies too and so on. Now lets imagine you have an ASP.NET MVC Project and you map your Entity to your ViewModel. You show your Model in your View as a form, but you only show the properties that you need in your view, not all that are set in your ViewModel. Then the user sends the Form back to you and your Controller gets the ViewModel back, but this time not all Properties are set, because your View only knew the ones that were shown. If you map your ViewModel back to your entity, all unitialized properties are in there default state and will overwrite the valid data f rom your entity.
Another Problem is, that AutoMapper uses Reflections to set the Properties. Normally the right to exist for an ORM is the possibility to easy implement an DomainLayer. The DomainLayer has some Validations, Calculation... on the Entity itself. If now the Properties set with Reflection it would ignore the Business logic and no Validation, Calculations.... would be executed.
So my advice is, Don't map to Entities ;)

Preventing StackOverflowException while serializing Entity Framework object graph into Json

I want to serialize an Entity Framework Self-Tracking Entities full object graph (parent + children in one to many relationships) into Json.
For serializing I use ServiceStack.JsonSerializer.
This is how my database looks like (for simplicity, I dropped all irrelevant fields):
I fetch a full profile graph in this way:
public Profile GetUserProfile(Guid userID)
{
using (var db = new AcmeEntities())
{
return db.Profiles.Include("ProfileImages").Single(p => p.UserId == userId);
}
}
The problem is that attempting to serialize it:
Profile profile = GetUserProfile(userId);
ServiceStack.JsonSerializer.SerializeToString(profile);
produces a StackOverflowException.
I believe that this is because EF provides an infinite model that screws the serializer up. That is, I can techincally call: profile.ProfileImages[0].Profile.ProfileImages[0].Profile ... and so on.
How can I "flatten" my EF object graph or otherwise prevent ServiceStack.JsonSerializer from running into stack overflow situation?
Note: I don't want to project my object into an anonymous type (like these suggestions) because that would introduce a very long and hard-to-maintain fragment of code).
You have conflicting concerns, the EF model is optimized for storing your data model in an RDBMS, and not for serialization - which is what role having separate DTOs would play. Otherwise your clients will be binded to your Database where every change on your data model has the potential to break your existing service clients.
With that said, the right thing to do would be to maintain separate DTOs that you map to which defines the desired shape (aka wireformat) that you want the models to look like from the outside world.
ServiceStack.Common includes built-in mapping functions (i.e. TranslateTo/PopulateFrom) that simplifies mapping entities to DTOs and vice-versa. Here's an example showing this:
https://groups.google.com/d/msg/servicestack/BF-egdVm3M8/0DXLIeDoVJEJ
The alternative is to decorate the fields you want to serialize on your Data Model with [DataContract] / [DataMember] fields. Any properties not attributed with [DataMember] wont be serialized - so you would use this to hide the cyclical references which are causing the StackOverflowException.
For the sake of my fellow StackOverflowers that get into this question, I'll explain what I eventually did:
In the case I described, you have to use the standard .NET serializer (rather than ServiceStack's): System.Web.Script.Serialization.JavaScriptSerializer. The reason is that you can decorate navigation properties you don't want the serializer to handle in a [ScriptIgnore] attribute.
By the way, you can still use ServiceStack.JsonSerializer for deserializing - it's faster than .NET's and you don't have the StackOverflowException issues I asked this question about.
The other problem is how to get the Self-Tracking Entities to decorate relevant navigation properties with [ScriptIgnore].
Explanation: Without [ScriptIgnore], serializing (using .NET Javascript serializer) will also raise an exception, about circular
references (similar to the issue that raises StackOverflowException in
ServiceStack). We need to eliminate the circularity, and this is done
using [ScriptIgnore].
So I edited the .TT file that came with ADO.NET Self-Tracking Entity Generator Template and set it to contain [ScriptIgnore] in relevant places (if someone will want the code diff, write me a comment). Some say that it's a bad practice to edit these "external", not-meant-to-be-edited files, but heck - it solves the problem, and it's the only way that doesn't force me to re-architect my whole application (use POCOs instead of STEs, use DTOs for everything etc.)
#mythz: I don't absolutely agree with your argue about using DTOs - see me comments to your answer. I really appreciate your enormous efforts building ServiceStack (all of the modules!) and making it free to use and open-source. I just encourage you to either respect [ScriptIgnore] attribute in your text serializers or come up with an attribute of yours. Else, even if one actually can use DTOs, they can't add navigation properties from a child object back to a parent one because they'll get a StackOverflowException.
I do mark your answer as "accepted" because after all, it helped me finding my way in this issue.
Be sure to Detach entity from ObjectContext before Serializing it.
I also used Newton JsonSerializer.
JsonConvert.SerializeObject(EntityObject, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });

Automapper: Mapping hierarchy

For my ASP.NET web application, I'm currently using Automapper to map from models (DTOs) -> view models. My view models have all string properties, because I'm using Mustache, a logic-less template engine.
I'm exposing an API to my website (via JSON, etc.), and what I'd like to do is perform the following mapping:
Model -> Base ViewModel -> Web ViewModel
Then, "Base ViewModel" can be serialized for my API (eg. with numerical values for currency). From there, I'll do a simple mapping for my "Web ViewModel" (eg. with formatted currency value strings, links, etc).
Problem is, I can't seem to get this to work. Defining the Model -> Base ViewModel mapping and Base ViewModel -> Web ViewModel mappings seperately isn't enough it seems to get my Web ViewModel, and if I explicitly add the Model -> Web ViewModel mapping, Automapper just tries to map directly, skipping the intermediate step which I rely on.
Can/should Automapper be used like this? I realize that I could probably explicitly just do two sequential conversions to achieve the correct result, but I thought I'd ask here to see whether I can get Automapper to handle the conversion in one step.
Well, I don't believe (or to be honest I don't know how) it could be possible.
But you could try
Create your Mappings
Model.CreateMap<Model, BaseViewModel>()...
Model.CreateMap<BaseViewModel, WebViewModel>()...
and try a generic helper like this, to be changed for your needs
public static void TwoStepMapping<TSource, TIntermediate, TDest>(TSource source, TDest dest) where TIntermediate : new()
{
Mapper.Map(Mapper.Map(source, new TIntermediate()), dest);
}
call :
TwoStepMapping<Model, BaseViewModel, WebViewModel>(model, webViewModel);

Restore one fetched entity out of many -- Core Data

This question covncerns my lack of understanding of how to use the core data undo manager and how to restore a NSManagedObject to its state before editing was done.
I am just learning my way around Core Data. I have my NSManagedObject classes set up with their dynamic accessors. I perform a fetch that returns several NSManagedObject entity results. Content from each of these entity results (first name, last name) get put into a table view, and then the user picks one out of the table for detailed view and then editing.
The detail view controller receives a pointer to the selected NSManagedObject entity. As the user edits the fields, the corresponding property value in the NSManagedObject entity is updated. This seemed like the cleanest way to manage these changes.
Now, rather than committing the changes using save, I want to provide a cancel-editing feature that rolls back to what is in the data base for that entity. I really only want to restore the one entity and not perform the entire refetch.
I tried rollback and I tried NSUndoManager (with beginUndoGrouping and endUndoGrouping), and that is not working. I don't think I understand what rollback is really supposed to do.
But in any case, I still want to restore the property values in just that single entity (taking the lazy approach to only fetch what is needed, which is the one entity) so that my detail view controller can refill its view with the correct information. Right now it is using the NSManagedObject entity values, which contain the edited values, which were cancelled.
I suppose I could just start the edit process by creating a copy of the NSManagedObject. If the cancel-editing button is pressed, I could copy it back into the original. (I might even be able to just replace the original with the copy by moving the pointer. But since the pointer has actually been passed through several objects, I'm not sure how to manage the retain number on the copy.)
Does anyone have any other suggestions?
Thanks
Using rollback should accomplish what you want and I'm not sure what it doesn't. It is probably an implementation detail error.
You can find the specific managed object/s that were updated but not yet saved by calling the context's updatedObjects.

Resources