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
Related
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.
I'm a junior web developer trying to learn more every day.
What it the best practice for you guys to performe MVC repository pattern with Linq?
The one I use:
Create extra clases with the exact name of my .tt files with CRUD method like getAll(), getOne(), Update(), Delete() filling my own class with the entity framework and returning this, or using the entity framework crude
this is an example of what I'm actually doing.
this is my getAll method of my class for example User
public class CEmployee : CResult
{
public string name{get;set;}
public string lastname{get;set;}
public string address{get;set;}
//Extracode
public string Fullname // this code is not in the .tt or database
{
get
{
return name + lastname;
}
}
public <List>CEmployee getAll()
{
try
{
var result = (from n in db.Employee
select new CEmployee // this is my own class I fill it using the entity
{
name = n.name,
lastname = n.lastname,
address = n.address
}).ToList();
if (result.Count > 0)
{
return result;
}
else
{
return new List<CResult>
{
new CResult
{
has_Error = true,
msg_Error = "Element not found!!!!"
}
}
}
}
catch
{
return Exception();
}
}
}
that the way I do all thing I return a filled of my type, but on the web I see that people return the entity type normaly, But I do this to manipulate my response, And if I want to return extra information I just have to neste a list for example, whats the best way guys, return mytype or return the entity type ?
PD, I also use this class like my ViewModel.And I do this for all my classes.
One of the projects I am currently one uses Dependency Injection to setup the DAL (Data Access Layer.) We also are using an n-Tier approach; this separates the concern of the repository from the Business Logic and Front End.
So we would start with 4 or so base projects in the application that link to each other. One of that handles the Data Access, this would be your repository; read up on Ninject for more info on this. Our next tier is our Domain which houses the Entities built by the t4 template(.tt files) and also our DTO's (data transfer objects which are flat objects for moving data between layers.) Then we have a service layer, the service layer or business logic layer holds service objects that handle CRUD operations and any data manipulation needed. Lastly we have our front end which is the Model-View-ViewModel layer and handles the controllers and page building.
The MVVM calls the services, the service objects call the data access layer and Entity Framework works with Ninject to access the data and its stored in the DTO's as it is moved across layers.
Now this may seem overly complex depending on the application you are writing, this is built for a highly scalable and expandable web application.
I would highly recommend going with a generic repository implementation. The layers between your repository and the controller vary depending on a number of factors (which is kind of a broader/bigger topic) but the generic repository gets you going on a good implementation that is lightweight. Check out this article for a good description of the approach:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Ideally in a MVC application, you will want to repositories in a different layer like in a separate project, let's call it Data layer.
You will have an IRepository interface that contain generic method signatures like GetAll, GetById, Create or UpdateById. You will also have abstract RepositoryBase class that contain shared implementation such as Add, Update, Delete, GetById, etc.
The reason that you use an IRepository Interface is, there are contracts for which your inherited repository class, such as EmployeeRepository in your case, need to provide concrete implementations. The abstract class serves as a common place for your shared implementation (and override them as you need to).
So in your case, what you are doing using LINQ with your DbContext is basically correct, but implementation like your GetAll method should be part of the generic/shared implementation in your abstract class RepositoryBase:
public abstract class RepositoryBase<T> where T : class
{
private YourEntities dataContext;
private readonly IDbSet<T> dbset;
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected YourEntities DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual T GetById(long id)
{
return dbset.Find(id);
}
public virtual T GetById(string id)
{
return dbset.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return dbset.ToList();
}
}
I would suggest you need to think about whether or not to return an error result object like CResult, and think about if your CEmployee and CResult should exist in this parent-child relationship. Also think about what you want to do with your CResult Class. It seems to me your CEmployee handles too many tasks in this case.
I'm new to C# and ASP.NET MVC and i'm trying to understand the repository pattern. I've read a whole lot of articles, but I just don't understand how to use it. I'm currently using LINQ to SQL to access my SQL Server 2005 database and for testing purposes I created two tables. I have an Employees table and an EmployeeContacts table. The pk of both tables is UserName.
Employees
UserName
LastName
FirstName
Position
Email
Status
HireDate
EmployeeContacts
UserName
Contact1
Contact1Phone
Contact1Relationship
There is a one to one relationship between the two tables. An employee can be added, updated, and deleted and so can the data in the EmployeeContacts table.
So would I create a base repository to be used by both entities or should I create a repository for each entity separately? If anybody would be willing to show me some code that would be great.
So far, I have this Employee repository. I also have one for EmployeeContacts.
namespace MvcDirectoryLINQ.Models
{
public class EmployeeRepository
{
private TestDB_DataDataContext db = new TestDB_DataDataContext();
private UserName u = new UserName();
//
// Query Methods
public IQueryable<Employee> FindAllEmployees()
{
return db.Employees;
}
public IQueryable<Employee> FindRecentEmployees()
{
DateTime myDate = DateTime.Today.AddMonths(-6);
return from empl in db.Employees
where empl.HireDate >= myDate
orderby empl.HireDate
select empl;
}
public Employee GetEmployee(string UserName)
{
return db.Employees.SingleOrDefault(d => d.UserName == UserName);
}
//
// Insert/Delete Methods
public void Add(Employee employee)
{
// get the UserName which is created from the email
employee.UserName = u.ReturnUserName(employee.Email);
//Insert the new employee into the database
db.Employees.InsertOnSubmit(employee);
db.EmployeeContacts.InsertOnSubmit(employee.EmployeeContact);
}
public void Delete(Employee employee)
{
db.EmployeeContacts.DeleteOnSubmit(employee.EmployeeContact);
db.Employees.DeleteOnSubmit(employee);
}
//
// Persistence
public void Save()
{
db.SubmitChanges();
}
}
}
I have a class for an EmployeeFormViewModel:
namespace MvcDirectoryLINQ.Models
{
public class EmployeeFormViewModel
{
//Properties
public Employee Employee { get; private set; }
public EmployeeContact EmployeeContact { get; private set; }
//Constructor
public EmployeeFormViewModel(Employee employee, EmployeeContact employeeContact)
{
Employee = employee;
EmployeeContact = employeeContact;
}
}
}
Code for EmployeeController:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(string UserName, FormCollection formValues)
{
Employee employee = employeeRepository.GetEmployee(UserName);
EmployeeContact employeecontact = employeecontactRepository.GetContact(UserName);
try
{
UpdateModel(employee);
UpdateModel(employeecontact);
employeecontactRepository.Save();
employeeRepository.Save();
return RedirectToAction("Details", new { UserName = employee.UserName });
}
catch
{
foreach (var issue in employee.GetRuleViolations())
{
ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
return View(new EmployeeFormViewModel(employee, attendingID));
}
}
In my View, i inherit from #model MvcDirectoryLINQ.Models.EmployeeFormViewModel. My Employee data saves correctly but the EmployeeContacts don't and I have no idea why.
Am I implementing the repository pattern correctly?
The main goal when using the Repository Pattern (as far as I understand it) is to decouple your application from using a specific Data Access Layer. You haven't done that here because you create I can see that your EmployeeRepository class does not implement an interface. You really want to have something like EmployeeRepository : IEmployeeRepository
Then, in your Controller code, you can pass around an IEmployeeRepository instead of working concretely with your EmployeeRepository. This will give you two benefits:
Should you ever need to switch the backend code, you only need to make another class that implements the interface.
When you go to test your Controllers, you can pass around a so called mock object that implements the interface instead of hitting the actual database, which slows your tests down and also breaks Unit Testing.
Another thing I noticed is that you spin up a DataContext inside your repository. If you wanted to make changes to multiple different types of objects you would therefore have multiple DataContexts open, which I don't think is what you want, since your changes won't be transactional. You may want to look into the Unit of Work Pattern for a solution.
When learning about a pattern, try to figure out the main benefit first before trying to implement it. In some cases it may not make sense. Please let me know if you would like me to elaborate on anything. Good luck.
So would I create a base repository to be used by both entities or should I create a repository for each entity separately?
The general rule when using the repository pattern is that there should be one repository class per each primary entity type. Can the EmployeeContacts live independently of any Employee? If so, they should have their own repository. Are them always related to an Employee? If so, manage them by using the Employee repository itself.
I was wondering what is the best approach to having a select list on a form which contains values from a database without duplicating any code.
What I thought would make sense would be to load this data in the controller and pass it to a view model, so I can use SelectListFor<> or whatever in order to generate the list. However this means that I have to duplicate all the list loading in both the GET and the POST methods. The other way I can see would be to pass the database context into the view model constructor and have it load the list , but this then presents two more issues:
1) Should the view model know about the database context?
2) I then cannot use model binding by accepting the view model type as a method argument because it does not have a no-argument constructor (if I create a no-argument constructor then it won't have the lists if I want to redisplay the view containing the form).
Is there a better way to do this? This seems like it must be a fairly common scenario and any advice would be appreciated.
We typically implement our lookups through a ReferenceDataRepository that gets used within the controllers in the same way as any other repository interaction. This repository will usually recieve a high number of calls for predominantly static readonly data so we may implement a derived CachedReferenceDataRepository over this using an abstraction of your caching scheme of choice (Session, AppFabric etc).
Why not get you db or repository or business rule - whatever you call it send back an IDictionary???
This example assumes you have a list of users, you will send back an Key with their ID and the Value with lets say first name + last name:
Then use this inside the view....
<%= Html.DropDownListFor(model => model.UserID, new SelectList(Model.AvailableUsers, "Key", "Value",Model.UserID))%>
model.UserID = Key
Model.AvailableUsers = IDictionary<int,string>
I create my lists in some helper code sometimes then I lookup those values using this helper... so there is one centralized class (usually static) that will generate these "Users"...
Pass these users onto the view directly or alternatively a ViewModel as in your case- which is what I recommend
NOTE: You would not hookup your data context with the List/ Model Binding, that makes things too complex. Just take in the UserID as the selected user from the list then in your post handle apporpriately...
ViewModel:
public class UsersViewModel
{
public int UserID { get; set; }
public IDictionary<int,string> AvailableUsers{ get; set; }
}
In your post...
[HttpPost]
[ValidateAntiForgeryToken]
[DemandAuthorization(RoleNames.AdminUser, AlwaysAllowLocalRequests = true)]
public ActionResult AllUsers(int UserID)
{
try
{
//save to db or whatever...
return RedirectToAction("Index", "Users");
}
catch (RulesException ex)
{
ex.CopyTo(ModelState); //custom validation copied to model state
}
var _users= _service.GetUsers();
return View("AllUsers", new UsersViewModel
{
UserID = UserID,
AvailableUsers = _users
});
}
Well, in my opinion, you have to have context or repository object in your viewmodel to keep dry in this scenario. Furthermore, it is also correct that your viewmodel should not know about your database. To handle this issue you can have viewmodel's constructor accept an interface like
public Interface IUserRepository
{
public IEnumerable<User> GetAll();
}
and you can have your view model like
public class CreateVM
{
private IUserRepository _repo;
public CreateVM(IUserRepository repo)
{
_repo = repo;
}
public IEnumerable<SelectListItem> AvailableUsers
{
get{
return _repo.GetAll().Where(x=>x.isAvailable).Select(x=>new SelectListinItem{Text = x.UserName, Value = x.UserID});
}
}
}
Last piece of the puzzle is your DI setup. tell ur IOC container to inject IUserRepository in constructor of your viewmodel whenever it is instantiated. I don't know if DI can work when modelbinder creates an instance of your view model but it it does you are there at least in theory. your viewmodel does not know your repository but only an interface and your list is created at single point so you are dry too.
The biggest problem I see with passing IRepository to ViewModel is that this can easily cause performance issues - select n+1's are so natural in this case, that it is hard to avoid them. You want to have as little rountrips to DB as possible for the request, and having IRepository passed around all those multi-level ViewModels just doesn't help that.
Instead, you can introduce ViewModel factory which is responsible for creating ViewModels of desired type. MyViewModelFactory would depend on IRepository, and would create MyViewModel which is just plain DTO.
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);
...
}