Trying to display values from 2 tables, staff and department so i tried to perform a linq sql query but it doesn't work when i open my application in the web browser. New to MVC and this is my first time using linq to sql so I'm not sure whats wrong!
My error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List1[<>f__AnonymousType74[System.String,System.String,StaffDetails.Models.Department,StaffDetails.Models.Site]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[StaffDetails.Models.Staff]'.
Index view
public ActionResult Index()
{
IList<Staff> staffList = new List<Staff>();
var query = (from s in db.Staffs
from d in db.Departments
where s.DeptID == d.DeptID
select new
{
name = s.Name,
email = s.Email,
department = s.Department,
site = d.Site
}
).ToList();
return View(query);
}
Tables
The problem is you are passing an anonymous type but your view expects IEnumerable<Staff>, so while projecting your LINQ query you need to project Staff type like this:-
List<Staff> query = (from s in db.Staffs
from d in db.Departments
where s.DeptID == d.DeptID
select new Staff //here
{
Name = s.Name,
Email= s.Email,
Department = s.Department,
Site = d.Site
}).ToList();
Update:
Okay so your Staff is a mapped entity so in that case you should not be able to map it directly. You either need a DTO or alternatively you can first project the anonymous type and bring the operation in linq-to-objects using AsEnumerable() and then project from there like this:-
IEnumerable<Staff> staffList = (from s in db.Staffs
from d in db.Departments
where s.DeptID == d.DeptID
select new
{
name = s.Name,
email = s.Email,
department = s.Department,
site = d.Site
}).AsEnumerable()
.Select(x => new new Staff
{
Name = x.name,
Email= x.email,
Department = x.department,
Site = x.site
});
Related
I have created two tables: Claim and ClaimAttachments.
I'm trying to join them on ClaimID in order to get the filtered data from both the tables.
public ActionResult Index(int? search)
{
if (search!=null)
{
var Product = (from P in db.Claims
join C in db.ClaimAttachments on
P.ClaimID equals C.ClaimID
select new Claim
{
ClaimID = P.ClaimID,
ClaimBatchID = P.ClaimBatchID,
PatientControlNumber = P.PatientControlNumber,
PatientFirstName = P.PatientFirstName,
PatientLastName = P.PatientLastName,
ServiceFromDate = P.ServiceFromDate,
ServiceToDate = P.ServiceToDate,
});
return View(db.Claims.Where(x => x.ClaimID == search).ToList());
}
else
{
return View(db.Claims.ToList());
}
I'm able to get the searched result but from single table. The join is not working.
Currently you're only selecting from the Claims data:
return View(db.Claims.Where(x => x.ClaimID == search).ToList());
You have a join query just above that line of code:
var Product = (from P in db.Claims
join C in db.ClaimAttachments on
P.ClaimID equals C.ClaimID
select new Claim
{
ClaimID = P.ClaimID,
ClaimBatchID = P.ClaimBatchID,
PatientControlNumber = P.PatientControlNumber,
PatientFirstName = P.PatientFirstName,
PatientLastName = P.PatientLastName,
ServiceFromDate = P.ServiceFromDate,
ServiceToDate = P.ServiceToDate
});
But you don't do anything with the results of that query. It sounds like you meant to use the results of that query (which is in the Product variable, which incidentally should probably have a plural name since it's a collection) instead of just selecting from db.Claims. Something like this:
return View(Product.Where(x => x.ClaimID == search).ToList());
Note however that you're still only selecting data from one table. Though the join operation may alter the results of that selection. But the selection itself is here:
select new Claim
{
ClaimID = P.ClaimID,
ClaimBatchID = P.ClaimBatchID,
PatientControlNumber = P.PatientControlNumber,
PatientFirstName = P.PatientFirstName,
PatientLastName = P.PatientLastName,
ServiceFromDate = P.ServiceFromDate,
ServiceToDate = P.ServiceToDate
}
Notice how every value selected is from the P alias, which is defined here:
from P in db.Claims
So you're successfully joining the two tables, but only selecting data from one of the two tables. If you want to also select data from the other table then, well, you need to select data from the other table. For example, if there's a property on that table called SomeProperty that you want to select then you'd need to select it, and into an object which has that property.
For example, you might create a view model (let's call it ClaimViewModel as an example) which represents a combined record of the two tables, containing the properties you want from each. Then you'd select into that type:
select new ClaimViewModel
{
ClaimID = P.ClaimID,
ClaimBatchID = P.ClaimBatchID,
PatientControlNumber = P.PatientControlNumber,
PatientFirstName = P.PatientFirstName,
PatientLastName = P.PatientLastName,
ServiceFromDate = P.ServiceFromDate,
ServiceToDate = P.ServiceToDate,
SomeProperty = C.SomeProperty // <--- here
}
This would select the combined data into a list of ClaimViewModel objects, which you'd then filter based on your "search" and return to your view just like you do with the Claims objects now. And of course that view would need to be updated to expect a collection of ClaimViewModel objects instead of a collection of Claim objects.
I'm trying to write the query that will return only the specific information that I need to display in the view.
I have the following code:
var companiesWithResponsibleUser = from company in ctx.Companies
join user in ctx.Users on company.ResponsibleUserId equals user.Id
group new { company, user } by company.Id into g
select new
{
company = g.Select(t => t.company),
user = g.Select(t => t.user)
};
However this one returns the full data from both tables, which is very slow. I only need company name, address from company table and responsible user ID and full name from user table.
How can I rewrite this query so that it only populates these two objects with the data I want?
Following should help you:
var companiesWithResponsibleUser = from company in ctx.Companies
join user in ctx.Users on company.ResponsibleUserId equals user.Id
group new { company, user } by company.Id into g
select new
{
companyname = g.company.CompanyName
address= g.company.Address,
userid = g.user.UserId,
fullname= g.user.FullName
};
Please note that I haven't tested this.
I am not so sure but you can try this:
var companiesWithResponsibleUser = (from company in ctx.Companies
join user in ctx.Users on
company.ResponsibleUserId equals user.Id
select company.CompanyName,company.Address,user.Userid,user.UserFullName).ToList();
var Res = (from x in companiesWithResponsibleUser
group x by new
{
x.CompanyName,
x.Userid
} into g
select new {g.key.CompanyName, g.Address,g.key.Userid,g.UserFullName}).ToList();
You can add this part if error occur g.Address
x.CompanyName,
x.Userid,
x.Address
if field does not exists in select then user g.key.Address
I am new to .Net (and stackoverflow) so I am running into a few problems. One vexing problem is this linq query below. Some information about the code. CustomerCart is a separate Model class in my project where the products member is a list of products. If I remove the products from the select new CustomerCart portion it runs fine and the data is present. So I figure it is my syntax. Can I not put a linq statement inside an assignment constructor? Any help would be appreciative. Thank you in advance.
var k = from s in store.Customers
join p in store.ShoppingCarts on s.custId equals p.customerId
select new CustomerCart()
{
FirstName = s.firstName,
LastName = s.lastName,
products = (from j in store.Products
where p.productId == j.productId
select j).ToList(),
CartID = p.cartId,
CustomerID = s.custId,
};
**Edit
Error I receive: The model item passed into the dictionary is of type 'System.Data.Objects.ObjectQuery`1[productShop.Models.CustomerCart]', but this dictionary requires a model item of type 'productShop.Models.CustomerCart'.
Sorry for not placing the error message with my question.
Try this query instead:
var k =
from s in store.Customers
join p in store.ShoppingCarts on s.custId equals p.customerId
join j in store.Products on p.productId equals j.productId into products
select new CustomerCart()
{
FirstName = s.firstName,
LastName = s.lastName,
products,
CartID = p.cartId,
CustomerID = s.custId,
};
I am relatively new to entity framework and I've been trying to write a Linq statement with Lambda that includes a simple join. I have three tables: Staff - StaffRole - Role.
I want a staff member in a certain role that satisfies a certain condition. Its very simple to write this in regular SQL:
SELECT *
FROM Staff s
INNER JOIN StaffRole sr ON s.StaffId = sr.StaffId
INNER JOIN Role r ON sr.RoleId = r.RoleId
WHERE r.Description = 'SpecialisedHealthManager'
AND s.PrimaryShm = 0
Now, writing it in a Linq statement has not given me much luck. I'm thinking it would be something like this:
var actingShm = db.Staff.Join(db.StaffRole,
inner => inner.StaffId,
outer => outer.Role,
(outer, inner) => new
{
StaffId = inner.StaffId,
FirstName = inner.Staff.FirstName,
Surname = inner.Staff.Surname,
SamAccountName = inner.Staff.SamAccountName,
RoleId = outer.Description
});
Needless to say, this is not working..
Try using it this way:
var list = from s in Staff
join sr in StaffRole on s.StaffId equals sr.StaffId
join r in Role on sr.RoleId equals r.RoleId
where r.Description == 'SpecialisedHealthManager' && s.PrimaryShm == 0
select new
{
StaffId = s.StaffId,
FirstName = s.Staff.FirstName,
Surname = s.Staff.Surname,
SamAccountName = s.Staff.SamAccountName,
RoleId = r.Description
});
Look here if you realy want to do this with method syntax LINQ:
SO Multiple tables join with lambdas
Also look here:
http://msdn.microsoft.com/pl-pl/library/bb534675(v=vs.110).aspx
for Join extension method syntax. Usage presented in your code is wrong.
You should have your associations setup so you can do this...
var actingShm = from s in db.Staff
from r in s.Roles
where r.Description == "SpecialisedHealthManager"
select new
{
StaffId = s.StaffId,
FirstName = s.FirstName,
Surname = s.Surname,
SamAccountName = s.SamAccountName,
RoleId = r.Description
});
Are you using Entity Framework or Linq2SQL?
In a project i have a LINQ to SQL class which is OrderingSystem.dbml. I have the following code and in the select statement i want to retrieve only some of the rows from each table(Products - Categories). But of course the return statement that i have right now it is not correct. What is the correct return statement to use?? Thanks in advance
OrderingSystemDataContext database = new OrderingSystemDataContext();
public List<Product> GetProductsByCategoryID(int CategoryID)
{
var result = from p in database.Products
join c in database.Categories
on p.CategoryID equals c.CategoryID
where p.CategoryID == CategoryID
select new { p.ProductName, p.ProductPrice, p.ProductDescription, c.CategoryName };
//This is not working
return result.ToList();
}
On the select new you have to specify the type if you then want to retrieve a list of products, right now it creates an anonymous type. Try changing with :
OrderingSystemDataContext database = new OrderingSystemDataContext();
public List<Product> GetProductsByCategoryID(int CategoryID)
{
var result = from p in database.Products
join c in database.Categories
on p.CategoryID equals c.CategoryID
where p.CategoryID == CategoryID
//Assuming that these are the names of your properties
select new Product(){ProductName = p.ProductName, ProductPrice = p.ProductPrice, ProductDescription = p.ProductDescription, CategoryName = c.CategoryName };
return result.ToList();
}
It is because in the LINQ expression, you did a select new { } which creates an anonymous object, while your method returns a List of Product. You should change the select statement so it becomes select new Product() { ProductName = p.ProductName, ... the rest depends on the structure of your Product class.
By using the "select new" LINQ operation, you are creating an anonymous type. You can access the properties of that anonymous type within the current scope of the objects' creation, but you cannot return that anonymous type using any kind of recognizable type. You have two options:
Create a new class (e.g. Product) and create instances of that type as part of your select statement (as the other answers instruct)
Return the collection as List<object>. If you do this, you can still retrieve values from the objects, but you will need to do so via reflection. This can be quite valid if you are using the collection as the data source in a data binding scenario.
Your return type is Product but your query result uses an anonymous type.
Change this line:
select new { p.ProductName, p.ProductPrice, p.ProductDescription, c.CategoryName };
to something like this:
select new Product { Name = p.ProductName, Price = p.ProductPrice, Description = p.ProductDescription, Category = c.CategoryName };
EDIT:
Try just replacing it with:
select p;