Passing object from my Controller action method to my Repository method - c#

I am working on an asp.net mvc 5 web project and I have created a Repository Model class to interact with my database , and I am calling my repository from my action method. For example inside my Post Edit action method I have the following code:-
Repository repository = new Repository();
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(SecurityRole Role)
{
try
{
if (ModelState.IsValid)
{
repository.InsertOrUpdateRole(Role);
repository.Save();
return RedirectToAction("Index");
}
}}
And here is the repository model clas:-
public class Repository
{
private TEntities tms = new TEntities();
public void InsertOrUpdateRole(SecurityRole role)
{
role.Name = role.Name.Trim();
if (role.SecurityRoleID == default(int))
{
// New entity
//Code goes here
else
{
t.Entry(role).State = EntityState.Modified;
}
}
So my question is when I pass the object from my action method to my repository, how will Entity Framework treat the object ; will it create another copy inside the repository , or it will be tracking the same object ?. And if entity framework will be working on the same object inside the action method and inside the repository method in the session , so how entity framework keeps tracking the object ?
Second question , what is the best approach to follow; to pass the whole object from action method to repository (as I am currently doing), or instead of that to only pass the object id, and to retrieve the object again inside the repository model something as follow:-
repository.InsertOrUpdateRole(Role.RoleID);
and inside the repository
public void InsertOrUpdateRole(int id)
{
var SecurityRole = t.SecurityRoles.SingleOrDefault(a => a.SecurityRoleID == role.SecurityRoleID);
}

In C# objects are passed by reference. When you save a new role in your ActionResult you notice it has gotten an Id after the InsertOrUpdateRole call. EF is starting to track changes as soon something is attached to the context. So your first approach works fine (I use it as well). Make sure the model is passed to the InsertOrUpdateRole function with all it's values set, EF will overwrite the entire record so if you forget a property in your view it will become an empty value in the database. If you only want to update a few properties of the model use your second approach.

Related

How can I use Automapper to update an object in Entity Framework without nulling out properties?

I am trying to update an entity using Entity Framework and save it to the database. When the update is called, my service method retrieves the DTO, assigns its the values of the entity object that the UI passed to it, and then saves it to the database. Instead of manually assigning those values, i'd like to use Automapper, however when I do this, the values that I am not mapping are updated to null. Is there a way in Entity Framework or Automapper to prevent this?
Service method finds the existing object in the database, assigns the new entity's properties to it, then saves:
public void Update(MyEntity updatedEntity, int id)
{
var existingObject = db.tblmyentity.Find(id);
existingObject.name = updatedEntity.name;
existingObject.address = updatedEntity.address;
existingObject.phone = updatedEntity.phone;
db.SaveChanges();
}
However, there are values stored in fields of this object not accessible by the UI, such as who modified the object and when. Using AutoMapper to simplify this code (shown below) causes these fields to update to null:
public void Update(MyEntity updatedEntity, int id)
{
var existingObject = db.tblmyentity.Find(id);
Mapper.Map(updatedEntity, existingObject);
db.SaveChanges();
}
A good practice is to create a (service, api) model that contains only the relevant properties that can be updated. E.g.:
public class MyEntityServiceModel
{
public string name { get; set; }
public string address { get; set; }
public string phone { get; set; }
}
// this looks differently in recent versions of AutoMapper, but you get the idea
Mapper.CreateMap<MyEntityServiceModel, MyEntity>();
// your update functions looks the same, except that it receives a service model, not a data model
Update(MyEntityServiceModel updatedEntity, int id)
{
// same code here
}
This approach has the following advantages:
you obtain what you are asking for
safety: you do not risk updating more properties than you should since the service model clearly specify the properties that should be updated
serialization: the service model is more appropriate if you need serialization (EF models may include unwanted navigation properties)
Update function consumer becomes unaware of the data persistence library you are using.

Getting Id of the newly created object with EF

My repository is being exposed through UnitOfWork and Add method have only following code:
public void Add(Employee emp)
{
context.add(emp);
}
Then, from UnitOfWork, i am calling the Add() method with this code:
this.UnitOfWork.EmployeeRepository.Create(emp);
this.UnitOfWork.Commit(); // This calls SaveChanges() EF method
Now the issue is how can i obtain the Id of newly created object here?
Normally if your Id is Identity, when you save changes the Id will be automatically filled.
context.Employees.Add(emp);
context.SaveChanges();
var newId=emp.Id; //The Id is filled after save changes
A second variant could be using the GetDatabaseValues method:
context.Entry(emp).GetDatabaseValues();
var id = emp.Id;
After SaveChanges the employee entity wil have the new id assigned. Find a way to return it to higher level methods.

.Net MVC Entities and ViewModels...Same or Separate?

I am new to asp.net MVC and i have created a project using Entity Framework code first approach. I have put my POCO objects in to a separate class library called Entities.
Now i would like to get some data from my service class, which returns an Entity and output that to the View. here is some very basic code
// in POCO library
public class MyEntity() {
public int Id { get; set; }
public String Name { get; set; }
}
// in service library
public class EntityService() {
public MyEntity Get(int id) {
return new MyEntity() { Id=1, Name="This is my entity name" };
}
}
// controller in asp.net MVC web application
public MyController() : Controller
{
private EntityService _service;
public MyController(EntityService service) {
_service = service;
}
public ActionResult Index()
{
MyEntity entity = _service.Get(1);
return View(entity);
}
}
Now should i push MyEntity to the View, or should i be creating a separate ViewModel? Part of me thinks that creating a separate ViewModel would be best as to keep the separation between the Entities and my View, and also the "logic" to copy the fields i need would be in the controller. But another part of me thinks that creating a ViewModel is just going to be a near copy of the Entities so seems like a waste of time?
I would like to do it correctly, so thought i would ask here. Thanks in advance
Viewmodel is best solution.
You can put attributes(validations and other)
Your viewmodel can contain data from several data entities
As you say you get separation between the Entities and View
General approach get entities in controller and use some mapper library(I recommend emit mapper)
to map entity to your viewmodel

Edit Page not displaying Data

Any help is greatly appreciated!,
Everything was going great until I stumbled across this :(
When I click edit on my display table, It goes to the edit vue putting a 0 in my id text field but the rest of the form is blank?
What I have:
public ActionResult EditProduct(int? id)
{
Product prod = new Product();
return View(prod);
}
Thanks Guys!
In your code you are creating a new product and then sending that to the view, so it will be blank and have a zero as the id.
You need to retrieve your product and then pass it to the view. Maybe like this:
public ActionResult EditProduct(int? id)
{
Product prod = _productRepository.Get(id);// code to retrieve product from database
if (prod != null)
{
return View(prod);
}
else
{
return RedirectToAction("Error"); // or whatever...
}
}
You'll need to load your product from your data store by id instead of creating a new instance. Something like:
return View(db.Products.Find(id))
A great place to start with MVC is http://www.asp.net/mvc. There are plenty of tutorials for data driven mvc web sites.
To do your repository, create an interface named IProduct with a method Get, GetAll, Save, etc. Your repository class implementation ie ProductRepository.cs that implements IProductRepository has a reference to your ObjectContext (or DbContext is using ef 4.1)
Some prefer to have a generic IRepository interface - but as it was said to me 'a generic repository is a fairy tale'
Once you have that, create
YourRepository repository = new Repository(); //Some choose to pass in a context or inject one via unity, ninject, etc. this is a basic example.
Your repository has a method
private YourContextName _context = new YourContextName();
public Product Get(int productId)
{
return _context.Products.Where(o=>o.ProductId=productId).Single();
}
Thats all there is to it. Of course there are more advanced implementations but it is fairly basic.
http://blogs.microsoft.co.il/blogs/gilf/archive/2010/01/20/using-repository-pattern-with-entity-framework.aspx
http://www.codeproject.com/KB/database/ImplRepositoryPatternEF.aspx
http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx

Best way to update a LINQ model coming from a form

I'm designing forms in my ASP.NET MVC application that will receive objects. Here's what a typical edit action looks like:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, Person person)
{
peopleService.SavePerson(person);
return Redirect("~/People/Index");
}
The SavePerson call in the service does this:
public void SavePerson(Person person)
{
_peopleRepository.SavePerson(person);
}
And the SavePerson call in the repository does this:
public void SavePerson(Person person)
{
using (var dc = new SIGAPDataContext())
{
if (person.IsNew)
{
dc.People.InsertOnSubmit(person);
}
else
{
dc.People.Attach(person, true);
}
dc.SubmitChanges();
}
}
Now, this works well when I create the new record. However, when I update it without all the form elements, it nulls other fields. For instance, my Person model has a NationalityID property that is nulled if it doesn't show on the edit form.
What's the best practice to make the model update with just the fields that come from the form? Do I have to get the record from the database first and update it's properties manually like:
Person persistedPerson = peopleService.GetPerson(person.ID);
persistedPerson.Name = person.Name;
persistedPerson.DateOfBirth = person.DateOfBirth
// etc...
Or is there any other, cleaner way to do this?
Stephen Walther just posted an article describing this very thing in ASP.NET MVC. I would recommend you actually create your own set of DTO's and business objects on top of LINQ to SQL and treat LINQ to SQL as a language-integrated object database due to the gross complexities introduced by managing the DataContext, which according to Pro LINQ, should be kept alive as little as possible by design.
If you are going to use your LINQ to SQL entities as your DTO's, you should get the entity first, detach it, update it, re-attach it, then submit it.
In your controller, retrieve the existing person from the repository, then use UpdateModel/TryUpdateModel and pass in a whitelist of properties that you want to be updated. This would use the ValueProvider on the controller so there is no need to take the Person object in the action parameter list.
public ActionResult Edit( int id )
{
Person person = peopleService.GetPerson(id);
UpdateModel(person,new string[] { list of properties to update } );
peopleService.SavePerson(person);
...
}

Categories