MVC5 Entity Framework Partial Class Extended - asp.net

I've a problem about ASP.NET MVC5 and Entity Framework.
I work with an existing software database.
There is a table named "CLI" with lots of fields.
In my website, I've an Entity named "CLI".
A "CLI" can be a client or a delivery address (it's the same table). The only difference is the value of one field (C_LIV_SEUL)
I've a partial class "CLI" with DataAnnontations likes "Required" etc. on multiple fields.
The problem is that a Client and a Delivery Address doesn't have the same "Required".
Per example, for a Client, the field "C_NOM" is required.
For the Delivery Adress, "C_NOM" is not required.
In my view, when I've a form to update a Delivery Address, I don't display "C_NOM" because it isn't required.
But when I've a view to update a Client, I display "C_NOM" because it's required.
How can I do this ?
I think about inheritance, but I can't apply changes on datacontext (because it isn't a "CLI" entity), or add an Entity with the type "Client" or "DeliveryAddress"...
I also try to work with the ModelState (ModelState.Remove("C_NOM")), but when I SaveChanges the error persists.
Thank you all for help!

Related

Keep two different versions of an entity in Doctrine ORM

I'm working on a Symfony4/Doctrine/MySQL project with the following requirement:
Users can create entities (say posts) that are visible in the public frontend only after approval by an admin
When a user edits his post after approval/publication, the changed post needs to be approved again before the changes will become visible in the frontend. But while approval is pending the old approved version of the post must remain visible in the frontend.
This means I have to keep two versions of every "Post" entity: the approved version for the frontend and the work-in-progress version for the backend.
In past projects with similar requirements I tried different approaches to this problem:
Using "Versionable behavior" (this was in the Symfony1/Propel days using sfPropelVersionableBehaviorPlugin). For display in the frontend, if an entity was not approved I had to fetch the previous versions until the latest approved version was found.
Using a second entity/database table "ApprovedPost" with the same field definition as the main "Post" entity. When a post is approved by the admin, it will be copied to the ApprovedPost table. The frontend operates on the ApprovedPost table only.
What is the current best practice to implement such a behavior?
Because I am chellenging this problem right now, I want to share my approach.
The entity is a request for something. Everytime something changes, the changes should be preserved.
The approach:
On every edit action, a new entity row is created.
The entity has an "approved" flag and a createdAt Date field.
A request has a nullable one-to-one self relation (to point to the root/parent entity).
A custom repository is used fo accessing the database.
The typical find and findAll methods are modified: they search for the most recent version (by the createdAt field) that is approved.
Search is done via custom SQL/DQL: (WHERE id = ?1 OR WHERE parent-id = ?1) AND WHERE approved = true SORT BY created_at DESC LIMIT 1
More features can be added like enabled/disabled, deletion and so on ...
If you want to render the page server side and show the changed or old versions, I would recommend writing e.g. a Twig extension. You could implement different search functions in the repo and handle the representaion via the extension (sorting, referencing ...).
I created an API, which is able to do both: return the newest version and return all versions (with or without root or newest), but I use the latter one in the frontend only if necessary.
Like dbrumann stated, this is a opinionated approach (I like custom repos, because I can create them type safe and I can decouple application from persistence logic).

Spring Data, updating MVC partial entity

I'm new to Spring, Spring data and Spring MVC so I want to make sure I am not missing something.
I have a form for updating a User object, the form posts to a controller and the controller calls my service class that updates/add the entity using a UserDOA which extends CRUDRepository. I think this is a very basic test code.
The issue is that the form doesn't contain all the fields in my User class, so when the object is posted to the controller, only the fields that are contained in the form are populated and the entity fields that are not in the form are null. For example my user has 4 fields, firstname, lastname, age, password. The form only contains the first 3 fields so when the object is posted to the controller, the password field is null, that is as I expect. My issue is that if I then call save(entity) on my DAO it will update the user but that would include nulling the password field, which of course is undesirable.
Of course I could simply retrieve the original entity from the repository and merge it with only the fields that have been updated, but it seems to me this is a lot of work that would be very commonly required and typically spring has a solution to these types of generic tasks.
Did I miss something?
TIA

Symfony2: inject security context into model classes

I have propel classes that implement the preSave method. This is a hook where some fields can be automatically updated at each saving operation. This is needed in order to save the date of last update and the user of the last update.
The problem is that the model classes have no access to the service container, where I can get the user id (to set into the last update user field). Model classes cannot (at my knownledge) be declared as service, as these are kind of entities, instancied by propel itself and not by the service container.
The only solution I see is to have a "real" singleton (with a static instance) holding the user object, that I would instanciate during the bootstrap of the application, then any model class could access it.
Any better idea?
For anyone having the same propel, the given bundle only adds the EventDispatchor behavior to Propel, which means that you can manage propel events in the same as Symfony does, but it is separated from the Symfony container (it seams it is using it own container).
But glorpen/propel-bundle is doing this job very well, you can really define service that listen to Propel events, using simple tags.

what is db.SaveChanges() in asp mvc4

I searched on many site about savechanges but i dont get any proper
answer can any one tell me about
db.SaveChanges()
ModelState
db.SaveChanges() is not part of ASP.NET MVC - it's part of Entity Framework which is a set of Object-Relational-Mapping (ORM) tools for the .NET Framework. All this method does is persist (save) data in some of your classes (entities) into a database.
Useful links:
Scott Gu - Code-First Development with Entity Framework 4
MSDN - Entity Framework
ModelState is a part of MVC and allows extra binding metadata to be passed from the Controller to the View, which is typically largely about validation.
Useful links:
MSDN - Model State Class
MSDN - Performing Simple Validation
msdn says : It persists all updates to the data source and resets change tracking in the object context.
Example
To save the changes made to the entities to a database, we need to call the ObjectContext class SaveChanges method. In the example given below, the query retrieves the first customer from the entityset -Customer.
var customer = context.Customer.First();
The context.Customer returns the Objectset of Customer types and the LINQ extension method First() returns only the first customer.
customer.FirstName = "Yasser";
customer.LastName = "Shaikh";
context.SaveChanges();
We can edit the first customer details like name and address by assigning new values to the properties and call the SaveChanges() method to save the changes back to the database.
During SaveChanges, the ObjectContext determines which fields were changed. In this example, only FirstName and LastName are changed. So, only those two values are sent into the command. To identify the row to be updated in the database, the ObjectContext uses the value of the EntityKey property.
Please read:
http://msdn.microsoft.com/en-us/library/bb336792(v=vs.110).aspx
http://www.asp.net/mvc/tutorials/older-versions/models-(data)/performing-simple-validation-cs
This should help you a little. Basically the db.SaveChanges() method is used by Entity Framework to save current changes to the database and ModelState represents validation errors when e.g. the model is not valid.

Shared PKs and ObjectContext errors

I am using EF 4.3 in an ASP.NET WebForms application. I've started with model first approach with context object of type ObjectContext and POCO code generator (via T4).
At the beginning the Context was created at the beginning of every service method. While working on performance I decided to switch to context per web request. Unfortunately I have encountered an issue with Table-per-Type inheritance. I have two entities: Offer and OfferEdit. They are in a one to one relationship, and both share the same primary key. Basically an OfferEdit (OfferEdits table) is created once an Offer is being edited.
I query the context for a particular Offer entity more then once during web request. The error I get trying to execute:
var offer = Context.Offer.Where(o => o.Id == offerId).FirstOrDefault()
when this offer is already loaded to Context.Offer.EntitySet is
All objects in the EntitySet 'RuchEntities.Offer' must have unique primary keys.
However, an instance of type 'Ruch.Data.Model.OfferEdit' and an instance of type'Ruch.Data.Model.Offer' both have the same primary key
value,'EntitySet=Offer;Id=4139'.
Will appreciate all advice.
Sounds like you are misusing TPT inheritance. To make it clear EF inheritance works exactly same way as in .NET - the entity can be either of type Offer or OfferEdit. You can convert OfferEdit to Offer but it is still OfferEdit. It can never be of both types which means you can never have Offer entity with Id same as OfferEdit entity because same key cannot be used by two entity instances. You also never can change instance of Offer to OfferEdit because .NET doesn't allow you changing type of existing instance.

Resources