I am trying to create a partial view to display some data. My controller takes in a string itemID and performs a query based on that. When the partial view is called, it displays the same record over and over again.
Note: I changed the name of objects for security purposes.
[ChildActionOnly]
public ActionResult someAction(string itemID = "")
{
//Empty itemID
if(string.IsNullOrEmpty(itemID))
{
return RedirectToAction("Index", "Search");
}
var model = _db.someTable
.Where(r => r.itemID == itemID)
.OrderBy(r => r.col1)
.ThenBy(r => r.col2)
.Take(20);
return PartialView("_myView", model);
}
I have tried removing the OrderBy and ThenBy methods, but the result remain the same, (Order would not matter since they are duplicates...). When I remove the .Where method, it works as expected and displays 20 different records (though, not filtered by any means).
My view was created by Visual Studio using the List template. The view been proven working by removing the .Where method from the LINQ statement. Here are the important bits of the view:
#model IEnumerable<MyApp.Models.OperationData>
.
.
.
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.some column)
</td>
.
.
.
Any ideas as to what is wrong with this query?
EDIT: Tried the other LINQ syntax and ended up with the same results:
var model = from r in _db.someTable where r.itemID == itemID select r;
Winner winner chicken dinner!
Turns out the issue was with the mapping of model to table. The table I was working on has a composite key, which I didn't know about... After reading mipe34's bit about primary keys, I decided to do some investigation into the table structure. After discovering the composite keys, I added the mapping for the 2nd key and all works well.
This issue was extremely confusing since the SQL generated by LINQ worked perfectly fine when run in SQL Management Studio.
Thanks all!
Hit the breakpoint just after the model variable and see what SQL query is generated by LINQ - VS should display it for you. You can also try to execute the query (add .ToList() at the end of the query) to see the actual result, what is in the collection to distinguish if there is a problem in query or view.
Related
I am new to entity framework and I am trying to get my head around it. I am used to writing stored procedures which have all the data I need on a example by example basis.
I am under the impression that I can get all values from a particular table including the foreign key values direct using entity framework without having to write a select query which joins the data.
I have the following in my controller
public ActionResult Patient()
{
using (var context = new WaysToWellnessDB())
{
var patients = context.Patients.ToList();
return View(patients);
}
}
In my view I have the following
#foreach (var item in Model)
{
<p>
#item.FirstName #item.Surname #item.Gender.GenderDesc
</p>
}
I have two tables, Patient and Gender, GenderId is a foreign key which I am trying to get the GenderDesc from that table.
I am getting the following message
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Can someone explain why I cannot access GenderDesc. It does work if I remove the using() around my context, but I don't really want to leave that open, is there a way to get this to work still having the using around?
Thanks in advance.
Correct, you have disposed of the context as it is within a using statement, so anything you try to access from then on will not be able to be lazy loaded. The disadvantage with lazy loading is that it will perform a query for the gender for every patient you are iterating over, which is handy, but bad! I would load the related table at query time using Include.
You'll need a new import:
using System.Data.Entity;
And then include the related table:
var patients = context.Patients.Include(p => p.Gender).ToList();
That will result in a query which will join to your "Gender" table and you should be able to output item.Gender.GenderDesc in your view.
I'm trying to write some LINQ to join these tables but it's giving me errors. Here's my code
public PartialViewResult Getjobs(int id)
{
using (var db = new MTEntities())
{
var jobs = db.jobs.Include(j => j.jobslist)
.Include(jl => jl.jobslist.model_jobslist
.Where(aa=>aa.jobslist.JobsListID==jl.jobslist.model_jobslist.JobsListID))
.Where(bki => bki.BookingID==id)
.ToList();
if (jobs != null)
{
return PartialView("_JobDetails", jobs);
}
I'm trying to display the approx time from the model_joblist table for the incoming booking id.
<th>
#Html.DisplayNameFor(model =>model.jobslist.model_jobslist.ApproxTime))
</th>
Is this possible?
Error 5 'System.Collections.Generic.ICollection' does not contain a definition for 'JobsListID' and no extension method 'JobsListID' accepting a first argument of type 'System.Collections.Generic.ICollection' could be found (are you missing a using directive or an assembly reference?) Controllers\BookingController.cs 90 97 MechanicTracker
thats the error
There are multiple errors here. Firstly, I'd advise looking up include as include is not used for joins. You don't need it here at all to make the query work, but it will be useful for performance reasons.
Secondly, jobs being passed into _JobDetails will be of type List<job> so #Html.DisplayNameFor(model =>model.jobslist.model_jobslist.ApproxTime)) is wrong.
Thirdly, if you want to display the value of ApproxTime you need #Html.DisplayFor not #Html.DisplayNameFor. However, as the snippet is in a th element maybe you did want DisplayNameFor and you haven't posted the relevent bit of code at all.
To create your query you can just use:
var jobs = db.jobs.Where(bki => bki.BookingID==id).ToList();
Add Includes later if you need them for performance. See links at end of answer for help on this.
Then for display it will depend on exactly what you want. You will have a list of jobs so it may be something like:
foreach (var job in Model) {
...Some HTML...
job.jobslist.model_jobslist.ApproxTime.ToString("whatever date format you want")
...Some more HTML...
}
Some useful links:
Date and time formats
How to use the include statement
How to use the join statement
Data Tables in my application have lots of columns. Different users want different set of columns and in a particular order. The way I'm doing is, I have unique ID associated with each column for a table and I'm storing them in user preference. For example:
columnsToDisplay = "1,4,23,12,2,5,6,7,8,13,15"
In my view I'm using if else if to iterate though my table model (I'm using ASP.NET MVC) to render the table. I feel this is not the right way to do. Imagine a table with 50 columns and doing if else if 50 times! What's the ideal approach for this problem without using jQuery or any client side script plugin?
EDIT:
Here is what I'm doing now. I'm comparing each column with use preference.
foreach(var col in model)
{ if(col.name == id) {
<td>{{id}}</td>}else if(col.name == customerName) {
<td>{{name}}</td>}else if(col.name == balance) {
<td>{{balance}}</td>}else if(col.name == createdOn) {
<td>{{createdOn}}</td>}
}
.....
and so on...
If these tables are readonly (you don't need to be able to post them back to the server), you could probably get away with throwing your model data into an array of IDictionary objects. Then you could use the values of your columnsToDisplay (as an array of ints) to get the relevant column when creating the view.
Something like this, assuming your model is called model:
model.ColumnArray = { 2, 4, 6, 1, 0 };
Then, assuming the model has a property called Rows that has your IDictionary objects:
#foreach(var model in Model.Rows)
{
<tr>
foreach(var column in Model.ColumnArray)
{
<td>#model[column]</td>
}
</tr>
}
I have a ViewBag.People made up from a View;
var query = db.Vw_INTERACTPEOPLE.Select(p => new { p.PersonID, p.Fullname });
ViewBag.People = new SelectList(query.AsEnumerable(), "PersonID", "FullName");
Which all works fine, but in my view I have another model populating a table, and one of the items is populates is an JobcontactID (textbox) which links to the PersonID (i didnt design the database). So I want to search the viewbag for the ID and rather than displaying it I want to display the persons Fullname, so is there any viewbag search functionality?
I would suggest to pass that information in your ViewModel. It will keep it clean and maintainable in long run. Here is a good post: Use ViewModels to manage data & organize code in ASP.NET MVC applications
ViewBag is just a dynamic wrapper around ViewData (which allows the property invoked at runtime to become the key which will be used to look up the value in ViewData). You can query ViewData like this:
SelectList peopleSelectList = (from pair in ViewData
where pair.Key == "People"
select pair.Value);
Update So you wish to query the select list itself?
Here's a function defined in the razor view:
#functions {
public string FindPersonName(string id)
{
return (from item in ViewBag.People as SelectList
where item.Value == id
select item.Value).FirstOrDefault();
}
}
#functions.FindPersonName(jobContactId)
I'm trying to bind columns from two different tables in to gridview using Linq To Sql
Here's the bind:
var q = (from o in mail.tblmails
join c in mail.tblstaffs on o.staffId equals c.id
select new { o, c });
return View(q);
and here is where I'm calling the bind in my View.
.Columns(columns =>
{
columns.Bound(o => o.dateAdded).Format("{0:MM/dd/yyyy}").Width(80);
columns.Bound(o => o.companyId);
//columns.Bound(c => c.staffId);
columns.Bound(o => o.subject);
columns.Bound(o => o.dateArchived);
})
I'm getting an error
Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Data.Linq.DataQuery1[<>f__AnonymousType06[System.Nullable1[System.DateTime],System.Nullable1[System.Int32],System.String,System.Nullable1[System.DateTime],System.String,System.Int32]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[ffs.Models.tblmail]'.
I have a feeling that the issue may have something to do with the line
< % Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage>"%>
but I'm not sure what to do to fix it.
I'm using the telerik grid extension.
Any help would be great, thanks.
What you are doing now (and doing wrong also) is sending the query data directly to the view. This is considered bad practice. Although possible to acces the resulting anonymous type, this method will cause to do your data acces during the view instead of in the controller.
What I recommend is you make a model (class) to represent the data and return a list of those entities (your model) to the view using:
<% Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<List<yourCreatedModelClass>>"%>
Watch the part where you tell the view you are handing it a list of your objects rather than just a clean view.
Some related problem and solution is discussed here
I think the problem (looking at your error message) lies in the fact that you are trying to pass an anonymous type around while the view is expecting an IEnumerable<tblmail>.
What you want to do is create a data structure like:
public class Model
{
public tblmails Mails { get; set; }
public tblstaff Staff { get; set; }
}
Then in your linq query you would put o into Model.Mails, and then put c into Model.Staff. You then pass your IEnumerable<Model> result into your view, and hook your view up so it is expecting IEnumerable<Model> as the model.