MVC save two Models - entity-framework

I have a problem that's probably easy to fix, but I don't find the right way to do it.
I have the following situation:
I am building a web application where I use several forms. One of the forms uses and displays two Entity Framework models that have a 1:1 relation. It's one entity for all BaseData (common Data) and one entity for AdditionalData (specific Data). The form's Model is of type AdditionalData, which has a NavigationProperty of type BaseData.
When I want to save this "form" i.e. the two entities - what is the best way to do that?
Do I call two Actions seperately, like "Save(BaseData) then Save(AdditionalData)"(how?)?
Do I redirect from one Save Action to the Other one (also how?)?
Do I need to build a new Model to accomplish what I need (maybe with a special ModelBinder) or do I only need a special ModelBinder?
Can I manually invoke the ModelBinder for the "BaseData" manually from the Save Action of the AddidionalDataController?
Am I doing it completely wrong in the first place?
Thank you for any help!

Related

Symfony2: Difference between those metodology "Embedded Form" and "Data Transformer"

Consider the following scenario
We have a simple database that involves two entities: user and category.
For our hypothesis let's say that a user can have only a type of category and a category can be associated with n users.
Now, consider a web page where a user - say ROLE_ADMINISTRATOR - could edit user table and associate them to a different one category.
As far I know (and I'm still new to symfony in general) if I use Doctrine and symfony2 in tandem, with - let's say - annotation method, i'll have two entity (php classes).
Embedded form
I will create a form that will show the user and, for show - and persist, of course! - also his category I "choose" to follow the "embedded form" strategy.
Having said that the entity has been created, i'll have to create a form for category (suppose that into formBuilder I'll add only id attribute of the category).
After that I have to add to formBuilder of UserType class the previous form and, with "some kind of magic" the form will render (after the appropriate operations) as magic and just as magically, when i'll post it (and bind, and so on) back all the informations will be persists onto database
Data Transformers
A.K.A. trasnform an input of a form into an object and vice versa.
In that way I'll have to define a - let's say - CategorySelectorType that into his builder, will add a Class (service ?) that will do those transformations.
Now we define the data transformer itself that will implement the DataTransofmerInterface (with his method and so on...)
The next step will be register that entity into services and add into UserType the form that will use this service.
So I don't understand any "strong" difference between those two metodology but "reusability" of the service. Somebody can offer me a different point of view and explain me the differences, if any?
A data transformer does not replace a embedded form, it rather enhances forms and wraps data transformation nicely.
The first sentence on the cookbook page about Data Transformers sums it up nicely:
You'll often find the need to transform the data the user entered in a
form into something else for use in your program.
In your example above, you could add a drop-down list of categories so the admin can select one for the given user. This would be done using a embedded form. As the category field is the id of an existing category, there is no need to transform the data.
For some reason you now want the admin to be able to enter a free text of the category. Now you need to do some tranformation of the text into the object in question. Maybe you want him to be able to either add a new or select a current category with this text field. Both is possible by using a data transformer which takes the text and searches for the category. Depending on your needs, not existing categories can be created and returned.
Another use case is when a user enters data which needs to be modified in some way before storing them. Let's say the user enters a street, house number and city but you want to store the coordinates instead.
In both cases it doesn't matter if you embed the form into another!
Could you do that in your controller? Of course. Is it a good idea to do such things in the controller? Probably not, as you have a hard time testing (while doing it in the transformer let you unit test the transformation nicely) or reusing it.
UPDATE
Of course it is possible to place the transformation code someplace else. The user object itself is not a good place, as the model should not know about the entity manager, which is needed to do the transformation.
The user type would be possible, but this means that it gets tied to the entity manager.
It all adds up to the very powerfull concept of Separation of concerns, which states that one class should only do one thing to make it maintainable, resuable, testable and so on. If you follow this concept, than it should be clear that data transformation is a thing on its own and should be threated as such. If you don't care, you may not need the transformation functionality.

Is there a way of avoiding 2 repository objects for the same database table?

Im currently working in a team that uses EF as the ORM of choice.
We have a common project that contains many EDMX files.
The reason for this is to keep the EDMX files small and manageable while also allowing them to focus on a conceptual set of tables on the database.
Eg
Orders.edmx
Users.edmx
Trades.edmx
These all point to a different set of tables on the same db.
I now need to add the user table to the Trade.edmx file. Since the user table is already in the user.edmx file, this creates the same User type twice under a different namespace which means I would need 2 UserRepository objects.
Common.data.trade.User
Common.data.users.User
Is there a way of avoiding 2 repository objects for the same table?
Any suggestions would be greatly appreciated
If you are using POCO generator you can update template for Trades.edmx to not generate new User class and its context template to use User class from Users namespace. EF matches POCO classes with entities in designer only by the class name (namespace is omitted) so it will work.
The disadvantage is that you have User entity in two mapping files and you must update it in both files or your application throw exception at runtime.
The reason for this problem is your architecture - at the beginning you wanted separated models but know you want to combine entities from different models. Those are contradicting requirements. Either use separated model where Trade knows only userID without any navigation property (like if it is defined in another database) or move all entities to single EDMX to support your new requirements.

Poco+Entity Framework 4. Where should I add my methods for working with Poco classes?

I've tried to use Entity Framework 4 and POCO for my MVC 3 project. May be, I don't understand the main idea of this ORM, but the problem is following:
I added ADO .NET Entity Data Model and make model according to database.
I clicked Add Code Generation Item and added ADO .NET POCO Entity Generator.
It makes classes for every database table.
I want to add some methods to work with data (Add, Update, Delete, GetAll etc) to appropriate models.
For LINQTOSQL I added partial classes and placed them to Models. But now I can't do it because:
a) Models folder has classes with the same names, which was created by POCO.
b) If I place my partial class in the another folder, it will be another namespace - so, such classes won't be partial one.
c) If I place my code in POCO classes, it can be destroyed during update POCO.
How can I use it? Where sould I place my methods for data working?
Is the best way to make for POCO and EF the other project - http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx?
First of all you don't have to write your CRUD inside POCO,
There are many places where you can do it like in edmx.cs file or write one more layer which is called as CRUD Services which handles the Database operations using context object.
Now coming to your questions,
Create separate Models folder and place the Model classes in there.
Your Model class may like this,
EmployeeDepartmentModel
{
prop EmpList List(Emp);
prop DeptList List(Dept);
//Emp and Dept are my POCOs
}
So now I have to fill both of these list(Your CRUD question),
For that, I will Create one method in Controller class(its better to write such logic in some another library, but for time being I suggest you to create in Controller),
FillTheModel()
{
EmployeeDepartmentModel.EmpList = EDMX.GetAllEmployees;
EmployeeDepartmentModel.DeptList = EDMX.GetAllDepartments;
}
Now you can bind this model with your view.
You can place the partial classes in another folder and modify the namespace.
I agree with allisewell, but if you really want to add parts to partial classes, give files another name,
e.g. MyPoco.Part2.cs or modify t4 template to name generated files
e.g. Poco.Generated.cs

Data sharing amongst JPA Entities

Setup: I have a simple web app that has a handfull of forms, each on a separate page. These forms represent patient data. There is a one-to-one relationship between patient and all these forms/entities. Each form maps directly to a db table and a JPA entity, maybe not the best architecture but it works and is simple.
Question: If form/entity A and form/entity B share a common chunk of data (one of more fields), what is the best way to handle that in JPA. I.E. - If the data gets inserted via form A, I need it to show up in form B as existing data and vice versa. In other words its logical for both entities to contain that data. I believe I will have to move the common data into its own entity and define the relationships that way, but I have tried many different ways and none gets me all the way, at least with basic JPA. Can this be done through pure JPA relationships or will I have to write a bunch of code to make this happen manually. Not looking for code specifically, just the correct way to model this data. Thanks.
If the forms have separate tables with duplicate columns for the common data, then you cannot directly share the data. You will need to copy the data from one Entity to the other in your application. You could use a Embeddable to define the common data, but would still need to copy this Embeddable from one form to the other.
If you put the common data in a 3rd table, then you can share the data. Form A and Form B would define a OneToOne relationship to the common data.

How to get Entity Framework and MVVM to play nicely together?

I'm would like to use both EF and MVVM and am trying to see how they fit together. I can't find much in the way of examples so hope you guys can answer a few questions.
Let's say I have a single table in a database called Customer. I run the EF designer and get a data model.
The next step is to run some linq to get data out of the data model. Let's create a new class called CustomerRepository to do this.
Now I'm guessing the Model would call CustomerRepository.GetCustomers to get a list of customers.
Here is my question - CustomerModel has a list of customer objects that were defined by EF in the data model. How do I add validation attributes or any kind of validation to it?
There just seems to be a bit of a disconnect between EF and MVVM. I'm sure some of you have hit this before - any ideas? Any better ways of approaching this?
Cheers
Steve
The validation, the business rules, the presentation of your Customer object should live in the ViewModel that will serve as a controller or presenter for your View.
In terms of how to create that ViewModel, you have a couple of options:
Include the Model as a property of the VM, and pass the model instance into the VM's constructor. You can then expose the Customer's properties and just wire them through to the underlying Model's corresponding properties.
Generate a ViewModel using T4 templates and Reflection (or preferably Introspection) to 'read' the Model, and generate the properties that will map directly to it.
Now you can add custom validation rules to the VM, such that when the appropriate command is sent from the View you can perform your business rules, and if appropriate you can update the Model using EF's API to persist those changes back to the database...