LINQ to SQL return statement - c#

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;

Related

I try to return a List type from AccessLayer to a datagrid on Windows form but get ArgumentNullException

I am trying to keep developing my program in order to improve my knowledge on C#
But I am stuck again.
Problem is
I am trying to call a method inside Business layer in order to fill my product datagridview.
here you can see my screen shot
public List<Product> GetProductWithCategories()
{
using (DenemeContext context=new DenemeContext())
{
var query = (from pro in context.Products
join cat in context.Categories
on pro.CategoryId equals cat.CategoryId
select new
{
ProductID = pro.ProductId,
ProductName = pro.ProductName,
ProductCategor = cat.CategoryName
}).ToList();
return query.ToList();
}
I am getting an error in return of the query. I try to convert the query into Ienumerable as the method is a List method.
How can i get over this problem? ( I can list the table with put this code inside the main form, but I would like to take the result insied the Business layer).
and you can check my codes on Github, if you wish
thank you.
You need to specify class name Product after select new statement. This will indicate compiler you return a list of concrete class. Without a class name you return a list of anonymous type which is not equal to List<Product>
public List<Product> GetProductWithCategories()
{
using (DenemeContext context=new DenemeContext())
{
var query = (from pro in context.Products
join cat in context.Categories
on pro.CategoryId equals cat.CategoryId
select new Product
{
ProductID = pro.ProductId,
ProductName = pro.ProductName,
ProductCategor = cat.CategoryName
}).ToList();
return query.ToList();
}
}

#C Razor Join Data LINQ

Attempting to display a table with a join on the Rating
to the ID within the Ratings table. I'm hitting an issue with the join within my statement.
var Movie = from u in _context.Movie
join g in _context.Ratings
on u.Rating equals g.ID
select (a => new List
{
Ratings = u.Rating,
MovieRating = g.MovieRating
});
Movie = await Movie.ToListAsync();
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
You have some weird syntax like (a => new List { ... Not sure where you are going with that.
Do you have a class named List? are you trying to get a List? Why is "a" in there...since it is not referenced anywhere. You also try to change the type of the Movie variable in your code, the var keyword doesn't work that way. On the first line, you assign a IQueryable< T> to it and later on you try to assign a List< T> to it.
try something like this:
var movieQuery = from u in _context.Movie
join g in _context.Ratings on u.Rating equals g.ID
select new
{
Ratings = u.Rating,
MovieRating = g.MovieRating
};
var movies = await movieQuery.ToListAsync(); // query will be executed here
The example code above uses an anonymous class as result so movies will be of type List< T> where T is an anonymous class, if you do have a class called List (for some reason) representing a single result item, then use
select new List { ...
instead of
select new { ...
and if you don't wanna split the query / actual list into 2 variables, you can do something like:
var movies = await (from u in _context.Movie
join g in _context.Ratings on u.Rating equals g.ID
select new
{
Ratings = u.Rating,
MovieRating = g.MovieRating
}).ToListAsync();

LINQ Convert var collection to a specific collection type

I have this code:
public class ExistedProducts
{
public int productID{get;set;}
public int productQte{get;set;}
}
..
..
..
public List<ExistedProducts> GetStock()
{
var result = from p in Products
join st in Stock on st.ProductID equals p.ID
select new{ExistedProductID=p.ID,ExistedProductQte = st.Qte};
return result.Cast<ExistedProducts>.ToList();// exception here
}
My first question, can I directly produce the typed collection from the query?
If not, how can I do the casting (i called the Cast() method but a raised exception saying impossible to do cast from
'<>f__AnonymousType0`2[System.Int32,System.Int32] ?
I want to avoid the copy by loop!
Yes instead of projecting anonymous type you can directly project your type ExistedProducts like this:-
var result = (from p in Products
join st in Stock on st.ProductID equals p.ID
select new ExistedProducts
{
productID = p.ID,
productQte = st.Qte
}).ToList();
return result;

MVC error "requires ienumerable instead of list"

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
});

LinqToSql: Select field from list used within a query

I perform a query on a table Installation to get a list of Ids that are needed to query a table Product on a different database (before you ask, it has to be this way, can't query across dbs). Here's what the list looks like:
class Installation
{
Guid InstallationId
Guid ProductId
}
List<Installation> installs;
I don't have any problems using this list for the query in to the Product table which looks like this:
var prods = (from p in context.Product
where installs.Select(i => i.ProductId).Contains(p.ProductId)
select new
{
ProductNumber = p.ProductNumber
// How do I get InstallationId from installs??
}).ToList();
What I need to know is how I can retrieve InstallationId from the list and store it in the new list?
Thanks in advance.
You should do a join
var products = (from product in context.Product
join install in installs
on install.ProductId equals product.ProductId
select new {
ProductNumber = product.ProductNumber
InstallationId = install.InstallationId
}
).ToList();
A slight refactoring of Jason's answer to allow for the LinqToSql exception.
var products = (from product in context.Product
where installs.Select(i => i.ProductId).Contains(p.ProductId)
select product).ToList()
var installedProducts = (from product in products
join install in installs
on install.ProductId equals product.ProductId
select new
{
ProductNumber = product.ProductNumber,
InstallationId = install.InstallationId
}).ToList();

Categories

Resources