ASP.NET MVC How to pass a joined data into view? - asp.net-mvc-3

I have the following code in my controller:
public ViewResult Index()
{
var q = from ci in db.City
join co in db.Country on ci.CityID equals co.CityID
select ci;
return View(q);
}
the database are as follow:
Table City: CityID, CityName
Table Country: CountryID, CountryName
in the index view how do I display both the CityName and CountryName:
#foreach (var item in Model) {
#Html.DisplayFor(modelItem => item.CityName)
and I can't get it to display CountryName :(
Thanks!

It doesn't work because you're only selecting the city in your query. You need to select both. Using an anonymous object is one way:
select new { City = ci, Country = co }
You should then be able to access item.City.Cityname, item.Country.CountryName etc.

Related

How to store join query data and retrieve using foreach loop from master layout page in asp.net mvc

I am new in asp.net mvc. I am trying to build role wise dynamic menu show in the view page. Each user can have multiple role.
I have a join query like:
My Controller looks like with join query:
var query= (from rMPageMap in db.RoleModulePageMaps
join userRole in db.UserRoleMaps
on rMPageMap.RoleId equals
join roleMaster in db.RoleMasters
on rMPageMap.RoleId equals roleMaster.Id
join modMaster in db.ModuleMaster
on rMPageMap.ModuleId equals modMaster.Id
join sModMaster in db.SubModuleMasters
on rMPageMap.SubModuleId equals sModMaster.Id
join pMaster in db.PageMasters
on rMPageMap.PageId equals pMaster.Id
where (userRole.UserId == appuser.Id &)
select new
{
rMPageMap.RoleId,
rMPageMap.PageMaster.Name,
roleMaster.Id,
roleName = roleMaster.Name,
modId = modMaster.Id,
moduleName = modMaster.Name,
subModuleId = sModMaster.Id,
subModuleName = sModMaster.Name,
pageId = pMaster.Id,
pageName = pMaster.Name,
parentPageId = pMaster.ParentPageId,
rMPageMap.AddData,
rMPageMap.EditData,
rMPageMap.ViewData,
rMPageMap.DeleteData,
rMPageMap.ShowInDashBoard,
rMPageMap.ShowInMenu
});
Session["rolemodulepage"] = query;
I find the values in the session while debugging. but i can not retrieve data from this using foreach loop in layout page.
Here is my view page that i try ro retrieve but does not work.
View Page:
#if (Request.IsAuthenticated)
{
var sessionVar = System.Web.HttpContext.Current.Session["rolemodulepage"];
foreach(var i in sessionVar) // error
{
#i.... // error
}
// So here how to retrieve data from session using foreach loop. I tried but does not work. Pls help. If you have some resource for dynamically mane show in view page pls share with me.
Can anyone explain that how to do it using showing dynamic menu by role based user in master layout page. Wihout login none can enter the site, pls explain with examples so that i can understand. Thanks in advance.
You query is generating a collection of anonymous objects which you cannot access in the view. Create a view model containing the properties you need and project your query into it, for example
public class MenuVM
{
public int RoleId { get; set; }
public string PageMasterName { get; set; }
....
}
and then modify the query to
var query = (from rMPageMap in db.RoleModulePageMaps
....
where (userRole.UserId == appuser.Id &)
select(new MenuVM()
{
RoleId = rMPageMap.RoleId,
PageMasterName = rMPageMap.PageMaster.Name,
....
}).AsEnumerable()
;
and then in the view you can cast the Session value and loop through it
var sessionVar = HttpContext.Current.Session["rolemodulepage"] as IEnumerable<MenuVM>;
if (sessionVar null)
{
foreach(var i in sessionVar)
{
....
However, as this is for generating a menu in a layout, I suggest you create move the code to a child action only method that returns a strongly typed partial view, for example in say CommonController
[ChildActionOnly]
public PartialViewResult Menu()
{
if (!Request.IsAuthenticated)
{
return null;
}
// Check if the session variable exists and if not, generate the query
// and add the result to session
return PartialView("_Menu", query);
}
and the _Menu.cshtml view would be
#model IEnumerable<MenuVM>
#foreach (var i in Model)
{
....
}
and in the layout, use
#{ Html.RenderAction("Menu", "Common"); }
to generate the html for the menu.

Contains method for comparing in multiple table

I am using EF code first. Two tables.
Company table (field: CompanyName) and Tag table (TagName). Company table has a link to the Tag Table
public class Company
{
public int Id { get; set; }
public string CompanyName { get; set; }
public virtual ICollection<Tags> Tags { get; set; }
}
I want to retrieve all companies where CompanyName contains string that is been passed and also retrieve all companies that have that string as a tag
var result = from c in _db.Company
select new CompaniesVM
{
Id = c.Id,
CompanyName = c.CompanyName
};
if (!String.IsNullOrEmpty(searchString))
{
result = result.Where(s => s.CompanyName.Contains(searchString));
}
My database contains:
Company name: test1
Company name: company test
if I run the code with searchString "test" it only captures the first record. Contains method does not capture the second record. Why is that? How do I capture all records with "test" string?
Also if I have TagName "test"
Company name: ABC Inc. Tag: TagName : test
How do I look into Tags table as well and get the companies?
I am using Many-to-Many example schema below
Can I do it all in one query? maybe using lazy loading method?
much appreciated if you can point me to a similar example or sample code
Contains is case sensitive so if your data is uppercase and your searchTerm is lower case, they won't match. If you want to ignore case when searching use result.Where(s => s.CompanyName.ToLower().Contains(searchString.ToLower())). To search the Tag table as well as Company table join them
from c in _db.Company
join t in _db.Tag on c.field equals t.field
select new { Companyname = c.CompanyName, TagName = t.TagName}
where !String.IsNullOrEmpty(search) && (c.CompanyName.Contains(search) || t.TagName.COntains(search)
Update for many to many, since you have the collection on Company:
from c in _db.Company
select new {
CompanyName = c.CompanyName
}
where !string.IsNullOrEmpty(search)
&& (c.CompanyName.Contains(search) || c.Tags.Any(t => t.TagName.Contains(search))

Using Linq Retrieveing the data to SelectListItem

I have class studentList
public class studentList
{
public static IEnumerable<SelectListItem> GetStudents(int? ID)
{
//code is required here
return ;
}
}
Iam getting ID into this method and now, I require all other IDs from the table, excluding the passed parameter ID using linq.
I have Student table which contains Two fieds StudentID and StudentName,
Now I require IDs and Names of the students in the above pattern..
Could any one help me...
Might like to read : SQL to LINQ ( Visual Representation )
var data= form s in Students
where s.StudentID != ID
select new {ID= s.StudenID,Name = s.StudentName};
image presentaion might be like

How can I pass any id to a linq join in [HttpGet] ActionResult for Edit

I am making a web application on MVC3, and I am using linq to communicate with the database.
I made a checkboxlist, where a user can select some options according to their choice and it gets saved in the databse table. The problem is in the Edit part.
The whole scenario is something like this:
The user can register as a restaurant owner or a Motel owner, I have assigned different Business_Type_Id as 1 and 2 for differentiating these two, I have assigned '2' for the Restaurant Business Type, and mapped the cuisines with the perticular business type in the same "Cuisines" table, by adding the "BusinessType" column into the table. the user will be assigned a Business_Id for their Business. I am providing a checkboxlist which generates its options from the database table "Cuisines" where I have given the cuisine list. From the front end the user can choose multiple cuisines according to their chioce what ever they provide in their restaurant. The choices may vary from one restaurant owner to the other, so I am storing the selected values for each and every Restaurant owner in a "BusinessCuisinesMapping" table, where I map the perticular BusinessId with the selected CuisineId by that perticular user.
Now to populate that cuisine list for edit or update I wrote a linq join, but I need to compare it with the Business_Id which is passed to the [HttpGet] ActionResult Edit. And this is point where I got stuck.
This is my linq join code which I am using in the controller:
[HttpGet]
public ActionResult Edit(int id)
{
using (var chkl = new BusinessEntities())
{
var data = (from CuisinesData in chkl.Cuisines
join BusinessCuisineMappingData in chkl.BusinessCuisineMapping
on new { CuisinesData.Id, id } equals new { BusinessCuisineMappingData.CuisinesId, BusinessCuisineMappingData.BusinessId }
where CuisinesData.BusinessTypeId == 2
select new CusinesDTO
{
Id = CuisinesData.Id,
Name = CuisinesData.Name,
IsSelected = BusinessCuisineMappingData.CuisinesId == null ? false : true
}).Distinct().ToList();
ViewBag.CuisineList = data;
}
return View();
}
This is my DTO class:
public class CusinesDTO
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
I want to comape the "id" with the "BusinessCuisineMappingData.BusinessId" field in my LINQ join, which I am getting through the [HttpGet] Actionresult Edit(int id). It prompts me an error while I try to implement it.
You cannot use a local variable in the join. However, you can use it in a Where clause. So if you do
join ...
on CuisinesData.Id equals BusinessCuisineMappingData.CuisinesId
...
where BusinessCuisineMappingData.BusinessId == id
you'll have the same effect.
"The type of the expressions in join clause is incorrect. Type inference failed in the call to 'Join'"
This suggests the types on either side of your JOIN are not equal. You are getting a compiler error; should be relatively easy to check the types on either side of your JOIN clause.
edit: rereading what you have put, I think something like the below is what you want to do:
[HttpGet]
public ActionResult Edit(int id)
{
using (var chkl = new BusinessEntities())
{
var data = (from CuisinesData in chkl.Cuisines
join BusinessCuisineMappingData in chkl.BusinessCuisineMapping
on CuisinesData.Id equals BusinessCuisineMappingData.CuisinesId
where CuisinesData.BusinessTypeId == id
select new CusinesDTO
{
Id = CuisinesData.Id,
Name = CuisinesData.Name,
IsSelected = BusinessCuisineMappingData.CuisinesId == null ? false : true
}).Distinct().ToList();
ViewBag.CuisineList = data;
}
return View();
}

Linq2Sql relationships and WCF serialization problem

here is my scenario
i got
Table1
id
name
Table2
id
family
fid
with one to many relationship set between Table1. id and Table2.fid
now here is my WCF service Code
[OperationContract]
public List<Table1> GetCustomers(string numberToFetch)
{
using (DataClassesDataContext context = new DataClassesDataContext())
{
return context.Table1s.Take(int.Parse(numberToFetch)).ToList( );
}
}
and my ASPX page Code
<body xmlns:sys="javascript:Sys"
xmlns:dataview="javascript:Sys.UI.DataView">
<div id="CustomerView"
class="sys-template"
sys:attach="dataview"
dataview:autofetch="true"
dataview:dataprovider="Service2.svc"
dataview:fetchParameters="{{ {numberToFetch: 2} }}"
dataview:fetchoperation="GetCustomers">
<ul>
<li>{{family}}</li>
</ul>
</div>
though i set serialization mode to Unidirectional in Linq2Sql designer i am not able to get the family value and all what i get is this in firebug
{"d":[{"__type":"Table1:#","id":1,"name":"asd"},{"__type":"Table1:#","id":2,"name":"wewe"}]}
any help would be totally appreciated
Well, the point is: your method GetCustomers only ever selects from Table1 - I don't see any reference at all to Table2, where your Family column is located......
You need to check into Linq-to-SQL JOIN's and how to fetch data from a joined table into your result set.
Something along the lines of:
[DataContract]
class JoinedResult
{
[DataMember]
public int Table1ID { get; set; }
[DataMember]
public string Table1Name { get; set; }
[DataMember]
public string Table2Family { get; set; }
}
[OperationContract]
public List<JoinedResult> GetCustomers(int numberToFetch)
{
using (DataClassesDataContext context = new DataClassesDataContext())
{
var q = from t1 in context.Table1
join t2 in context.Table2 on t1.id = t2.fid
select new JoinedResult
{ Table1ID = t1.ID,
Table1Name = t1.Name,
Table2Family = t2.Family };
return q.Take(numberToFetch).ToList();
}
}
and btw: you should really make numberToFetch an INT parameter! Let the caller make the conversion......
UPDATE: if you don't want to explicitly include the second table to be queried, you could instead add a DataLoadOption to your context:
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Table1>(t => t.Table2);
context.LoadOptions = dlo;
In that case, you tell LINQ to always include all elements from Table2 when it loads anything from Table1 - that should work, too.

Resources