How to update with Entity Framework in asp.net mvc3? - asp.net-mvc-3

I Have a table in my databse that one of the columns named NumOfView shows the number of clicks on a link. That link shows some info from a row in this table. I used onclick event in anchor tag like this:
onclick=#Url.Action("NumOfClicks", "AdvertiseHelper",new { id = Model.id[i] })
In NumOfClicks function I used this code
public void NumOfClicks (int id)
{
Ad ad1 = new Ad();
var advert = (from ad in storedb.Ads where ad.AdId == id select ad.NumOfView).First();
advert += 1;
}
advert
is the amount of
NumOfView
in table that I want to increase it 1 unit. but I don't know how to continue coding for update this value in table. Can anybody help me please?

This is the basics of how it should be done. First you have to select the record itself from the database rather than the number of clicks. Increment the number of clicks on that record, then submit the changes to the DataContext.
public void IncrementClickCount(int id)
{
var advert =
(from ad in storedb.Ads
where ad.AdId == id
select ad).Single(); // Select the row in the database represented by "ad"
advert.NumOfView++; // Perform the increment on the column
// SubmitChanges is how an update is done in Linq2Sql
// This requires a .dbml file for the database object file
// storedb.SubmitChanges(); // Assumes storedb is a valid DataContext, updates
// SaveChanges is how an update is done in EntityFramework
// It is recognizable because it uses an .edmx file for its database object
storedb.SaveChanges();
}
This was similarly asked in SO question: Entity Framework - Update a row in a table

Related

reading related data after a selection of a foreign key - MVC3 and EF4

I am new to MVC and EF and I have a question.
I have built a site with models views controllers etc.
On an edit view for a Case (pretty big model so I won't post it here) I have a FK to a Customer model using CustomerID. When a user selects a customer id from a drop down list, I would like to display CustomerName, CustomerPhone etc after the selection of the ID. I think I might need to do a post back for this to work?
Also, do I need to Include the related entities as part of the initial data "get"? I have read some detail on that but I dont fully understand how that needs to work.
Please let me know if I should post more info. Thanks!
Here is my ActionResult for Edit
public ActionResult Edit(int id)
{
Cases cases = db.Cases.Find(id);
//related data needs to loaded to show related data fields
//include related data entities
var v = db.Cases.Include("Customers");
ViewBag.TechnicianID = new SelectList(db.Technicians, "TechnicianID", "LastName", cases.TechnicianID);
ViewBag.BranchID = new SelectList(db.Branches, "BranchID", "BranchName", cases.BranchID);
ViewBag.EngineModelID = new SelectList(db.EngineModels, "EngineModelID", "EngineModelName", cases.EngineModelID);
ViewBag.CaseCategoryID = new SelectList(db.CaseCategories, "CaseCategoryID", "CategoryName",cases.CaseCategoryID);
ViewBag.Qualified = new SelectList(new[] { "YES", "NO", "PARTIALLY" });
ViewBag.CaseStatus = new SelectList(new[] { "OPEN/IN PROCESS", "CLOSED" });
return View(cases);
}
The line
var v = db.Cases.Include("Customers")
is what I am trying to use to load related customer data and then show in my edit view like this:
#Html.EditorFor(model => model.Customer.CustomerName)
Well it depends on what you are trying to do. You could include a model which holds all the required data and send it with every call on that page (initial empty ofcourse)
Once you selected the customer, do post-back and send the customerId to your application and return the same page with the desired model.
You could do that via AJAX too.
Also, do I need to Include the related entities as part of the initial data "get"?
Not sure if I understand what you are trying to say. You mean that you think you would have to send all customer's data down to the page and select the related data on client side?

Displaying records from database which are equal to logged on user

I have created an MVC3 application which needs to show user specific data. The problem I am having is trying to display records which are equal to #user.Identity.Name.
The following Linq to SQL has been used to try to accomplish this:
public ActionResult Index()
{
using (var db = new mydatEntities())
{
var details = from t in db.testadtas
where t.UserID == Viewbag.UsersRecord
select t;
return View();
}
}
(Update)
New to c# and Linq and finding it hard to write a query which will only display the logged on users records.
I have used the code below
MembershipUser currentUser = Membership.GetUser (User.Identity.Name, true /* userIsOnline */);
Viewbag.UsersRecord = currentUser.ProviderUserKey;
I have then input the Viewbag.UserRecord into a textbox which updates a database field with the UserID in a table I have created.
I now want to write a linq query to say if UserID = Viewbag.UserRecord then show record with the UserID only
Is this a correct method to use for showing logged on user records?
or is there any other way which I can implement this in MVC3?
Just use HttpContext.User.Identity.Name

Proper way to Edit an entity in MVC 3 with the Entity Framework using Data Model First approach?

A majority of the examples I see now are either using the Code First Approach or using an older version of MVC and the Entity Framework.
Assume I have a movie to update and I get to the Edit View, in the Edit method with the Post verb, what is the proper way to update a Movie? The first Edit Method below gets me to the Edit View with the populated Movie values and the second one is the one I want to use to update, I have tried some things, but nothing updates the data.
public ActionResult Edit(int id)
{
var movie = (from m in _db.Movies1
where m.Id == id
select m).First();
return View(movie);
}
[HttpPost]
public ActionResult Edit(Movie movie)
{
try
{
// TODO: Add update logic here
//What do I need to call to update the entity?
_db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Assuming that _db is derived from ObjectContext you have two options:
Change the state of the entity to Modified:
_db.Movies1.Attach(movie);
_db.ObjectStateManager.ChangeObjectState(movie, EntityState.Modified);
_db.SaveChanges();
This marks all properties of movie as modified and will send an UPDATE statement to the database which includes all column values, no matter if the values really changed or not.
Reload the original entity from the database and apply the changes to it:
var originalMovie = (from m in _db.Movies1
where m.Id == movie.Id
select m).First();
// You actually don't need to assign to a variable.
// Loading the entity into the context is sufficient.
_db.Movies1.ApplyCurrentValues(movie);
_db.SaveChanges();
ApplyCurrentValues will mark only those properties as modified which really did change compared to the original and the UPDATE statement which will be sent to the database only includes the changed column values. So, the UPDATE statement is potentially smaller than in the first example but you have to pay the price to reload the original entity from the database.
Edit
How does the second code example work?
When you run a query using the context (_db) Entity Framework does not only retrieve the entity from the database and assign it to the left side of the query (originalMovie) but it actually stores a second reference internally. You can think of this internal context "cache" as a dictionary of key-value pairs - the key is the entity primary key and the value is the entity itself, the same object as originalMovie refers to.
ApplyCurrentValues(movie) looks up this entity in the context's internal dictionary: It takes the key property value Id of the passed in movie, searches for an entity with that key in the internal dictionary and then copies property by property from the passed in ("detached") movie to the internal ("attached") entity with the same key. EF's change tracking mechanism marks the properties as Modified which were actually different to create later the appropriate UPDATE statement.
Because of this internal reference to the original entity you do not need to hold your own reference: That's the reason why originalEntity is not used in the code. You can in fact remove the assignment to the local variable altogether.
The example would not work if you disable change tracking when you load the original entity - for example by setting _db.Movies1.MergeOption = MergeOption.NoTracking;. The example relies on enabled change tracking (which is the default setting when entities are loaded from the database).
I cannot say which of the two examples has better performance. That might depend on details like size of the entities, number of properties which have been changed, etc.
It's worth to note though that both approaches do not work if related entities are involved (for example movie refers to a category entity) and if the relationship or the related entity itself could have been changed. Setting the state to Modified and using ApplyCurrentValues both affect only scalar and complex properties of movie but not navigation properties.
Your second edit method should look something like this:
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var movie = (from m in _db.Movies1
where m.Id == id
select m).First();
if (TryUpdateModel(movie))
{
_db.SaveChanges();
return (RedirectToAction("Index"));
}
return View(movie);
}

Create custom report with Entity Framework OR Enterprise Library?

I have developed a system for a client using ASP.Net MVC 3 and Entity Framework 4. The system is a small application which lets the client record and monitor his equipment, ie, he can add a piece of equipment such as a PC (record the Asset Number, Price, Warrenty Expires etc), assign it to a Category (ie PC System, Printer, Speaker etc) and also record the location of the equipment (ie Main Office, Store Room, 2nd Building). This all works fine, however, recently the client has asked for some reports to be built into the system.
Some reports are simple to do, ie, search by equipment asset number and then return all the additional info related to that. However, there is one report which he needs, this is to list all the Locations at the top of the report and then all the Categories at the left of the report just like a grid/ lookup table. Then this will show the total number of equipment categories in each location, for example, the total number of PC Systems at 2nd Building, total number of Speakers in the Store Room etc.
I was thinking, although I could be wrong, that this is not what Entity Framework was designed for, ie, returning objects, not datasets displaying calculations. Therefore, I was wondering, what would be the best way to do this?
I was thinking of possibly using Microsoft Enterprise Library and Stored Procedures to just return a dataset of results, however, maybe this is the wrong approach?
Again, any feedback would be much appreciated and I apologise if my request is a bit confusing.
Thanks.
What your customer wants you to show is called a pivot table. Take a look at the answer here: Pivot table in c# entity framework.
But if you have the following entities
public class Location {
public int LocationId { get; set; } // PK
}
public class Equipment {
public int EquipmentId { get; set; } // PK
}
public class EquipmentAtLocation {
public int LocationId { get; set; } // PK/FK
public int EquipmentId { get; set; } // PK/FK
public int Quantity { get; set; }
}
then building this table is nothing else than iterating over your m:n table EquipmentAtLocation and writing Quantity into the cell that is given by LocationId and EquipmentId. If you don't have that PK on that table, then you need to do a grouping by LocationId and EquipmentId on that table first.
var locations = ctx.Locations.Select((val, idx) => new { val.LocationId, idx }).ToDictionary(x => x.LocationId, y => y.idx); // get a map of location to index
var equipments = ctx.Equipments.Select((val, idx) => new { val.EquipmentId, idx }).ToDictionary(x => x.EquipmentId, y => y.idx); // get a map of equipment to index
int[,] pivot = new int[locations.Count, equipments.Count];
foreach (var entry in ctx.EquipmentAtLocations) {
pivot[locations[entry.LocationId], equipments[entry.EquipmentId]] += entry.Quantity;
}
I don't know if the data contract serializer is able to serialize multidimensional arrays, otherwise you have to use a jagged array. You should of course pack that into an object and also include the header information (the keys in the dictionary when ordered by value) so that you know which index means what.
Since you tagged this as MVC 3 - are you looking for a web interface for them to select a category, and the results show up? IF so, surely you can use Entity Framework. Simply use an Ajax request to a controller's method to then return your view with that data in it.
No procedure required - you can do this all in entity framework. Your left hand side is Entity A. When you click on one, it does an ajax request to /Category/Index/5 for example which them simply renders those results.

Foreign key relationships in Entity Framework v.1

I need to be to create an entity data model in the EF version 1, because my web host doesn't have Framework 4.0 yet. Below is just a simple example to show the problem.
I have 3 tables, one Users table, another Webpages table, and one table with Visits. The former two tables each have a one-to-many relationship with the Visits table (which basically works as a many-to-many relationship, only the Visits table has its own primary key and extra fields)
With the 4.0 version this works, but it doesn't with v.1. "Visits" has a count of 0, so the test string returns ""... Why, and how would I be able to access the foreign key relation in v.1?
UsersEntities context = new UsersEntities();
var users = context.Users;
string result = "";
foreach (var user in users)
{
foreach (var visit in user.Visits)
{
result += visit.Webpage.Url + "\n";
}
}
So the foreach loop loops through the users, which it gets ok, but the inner loop is never entered because there are no Visits returned. Again, in Framework 4.0 it works fine, using the same database.
So what's wrong?
Simply change your code to this:
UsersEntities context = new UsersEntities();
var users = context.Users.Include("Visits");
string result = "";
foreach (var user in users)
{
foreach (var visit in user.Visits)
{
result += visit.Webpage.Url + "\n";
}
}
Notice the Include(...) that tells EF to eagerly load each User's visits.
With that in place it should work.
Actually if Webpage is a navigation too, you might need:
Include("Visits.Webpage");
Hope this works

Resources