Unable to Find out Foreign Key related values without duplication - c#

I am trying to get all the Images and bullet_points of a single product. Images and Bullet_Points have foreign key Product_ID for reference. However I get a total of 40 rows as a result even when i only have 8 bullet_points ,5 images for a single product.what is it that i am doing wrong?
Below is my linq query that i am performing .
from p in Products
from i in Images
from s in Specifications
where p.ProductID==i.Product_ID && p.ProductID==5002
where p.ProductID==s.Product_ID && p.ProductID==5002
select new { p.ProductID,i.Image_URL,s.Bullet_Point}

Try the following query:
from p in Products
join i in Images on i.Product_ID equals p.ProductID into imgs
join s in Specifications on s.Product_ID equals p.ProductID into specs
where p.ProductID == 5002
select new { p.ProductID,
urls = imgs.Select(x => x.Image_URL),
bulletPoints = specs.Select(x => x.Bullet_Point) };
Why not to use navigation properties from Product? I can see your Product model has Images and Specifications properties. So you may also try:
Products.Where(p => p.ProductID == 5002).Select(p => new {
p.ProductID,
urls = p.Images.Select(x => x.Image_URL),
bulletPoints = p.Specifications.Select(x => x.Bullet_Point) })

Related

FirstOrDefault() in a LINQ left-join

I'm trying to setup a left-join query where I'm only pulling the FirstOrDefault record from the orders table, but it's not working the way I have it, is this even possible using LINQ?
var customerOrder = (from customer in customers
join orderJoin in orders.FirstOrDefault(x => x.CustomerId == customer.CustomerId) on customer.CustomerId equals orderJoin.CustomerId
join shippingJoin in shipping on customer.CustomerId equals shippingJoin.CustomerId into shippingGroup
from shipping in shippingGroup.DefaultIfEmpty()
select new
{
Customer.CustomerId,
Order = orderJoin,
Shipping = shipping
}).ToList();
make all your joins left joins and check for nullable values
var query = from company in companies
join product in products on company.CompanyId equals product.CompanyId into productleftjoin
from product in productleftjoin.DefaultIfEmpty()
join transaction in transactions on product.ProductId equals transaction.ProductId into transactionleftjoin
from transaction in transactionleftjoin.DefaultIfEmpty()
where transaction?.Cost * transaction?.Quantity>0
select new { company.CompanyName,productName=product.Name, extendPrice=transaction?.Cost* transaction?.Quantity };
You cannot use FirstOrDefaut as source of the query. There is antoher technnique with Take(1).DefaultIfEmpty(). Note that I have added default OrderBy because databse do not guarattee records order in such case and probably DateCreated or something like that should be used.
var customerOrder = (
from customer in customers
from orderJoin in orders
.Where(x => x.CustomerId == customer.CustomerId)
.OrderByDescending(x => x.Id)
.Take(1)
.DefaultIfEmpty()
join shippingJoin in shipping on customer.CustomerId equals shippingJoin.CustomerId into shippingGroup
from shipping in shippingGroup.DefaultIfEmpty()
select new
{
Customer.CustomerId,
Order = orderJoin,
Shipping = shipping
}).ToList();

How to connect 2 tables using LINQ ASP.NET

Images table structure:
Id
AccountId
Url
Slides table structure:
Id
AccountId
ImageId
I have two requests:
ViewBag.userId = user.Id;
ViewBag.images = context.Images.Where(c => c.AccountId == user.Id).Select(c => c);
ViewBag.slides = context.Slides.Where(c => c.AccountId == user.Id).Select(c => c);
Question:
How can I change the code ViewBag.slides = to get the result slides.ImageId = images.Id. I'm trying to get the url of the image.
You can do a LINQ join
var slidesForUser= ( from a in context.Images
join b in context.Slides on a.Id equals b.ImageId
where a.AccountId == user.Id select b).ToList();
slidesForUser variable will be a list of Slides (for those recors which matches the join and where condition). If you prefer to select only one property (Ex :ImageUrl), simply update the select part to be select b.ImageUrl
I hope get url picture.
If you just want the URL of the picture starting from slides you can use SelectMany
ViewBag.slides = context.Slides
.Where(c => c.AccountId == user.Id)
.SelectMany(c => c.Images)
.Select(i => i.Url);

How to group and join to get counts?

How can I join two tables to get the following results in the pictures below? I want to get the counts of the project names.
I know I can group by Project ID:
var TotalSupportsByProject =
from s in db.MySupportContext
.GroupBy(s => s.ProjectID)
.Select(g => new { ProjectId = g.Key, Total = g.Count() })
select s;
Join and group. It appears you are trying to get the counts of support for each of the projects.
var query =
from s in db.Support
join p in db.Project on s.ProjectId equals p.ProjectId
group 1 by p.ProjectName into g
select new
{
ProjectName = g.Key,
TotalSupport = g.Count(),
};
If you need to be able to include counts of projects with no support, some adjustments would have to be made. Assuming the Project table contains a all of the projects you need:
var query =
from p in db.Project
select new
{
p.ProjectName,
TotalSupport = db.Support.Count(s => s.ProjectId == p.ProjectId),
};

Linq to Sql selecting last row in a joined table

I am trying to select multiple table values using linq to sql
This is the code I wrote:
var query = (from p in context.Personel
join y in context.PerLanguage on p.ID equals y.ID
where p.Resign == false && p.KGBT > new DateTime(2012,1,15)
select new{ p.ID,p.NameSurname, y.EarnedDate,y.Degree}).ToList();
PerLanguage has a foreignkey "ID" to Personel. So PerLanguage table can have 2 or more data that has the same ID. I am expecting this piece of code to return me a List of items having the "last" entered Language data of different people.
What is the best way to do it?
try the following query.. basically we make the join, get the flat results, group it by id and descending sort the results within an ID and select the first record in every grouped result.
var results = context.Personel.Where(p => !p.Resign && p.KGBT > new
DateTime(2012,1,15)).Join(context.PerLanguage, p => p.ID, pl => pl.ID, (p, pl) =>
new { p.ID, p.NameSurname, pl.EarnedDate, pl.Degree }).GroupBy(r => r.ID)
.Select(g => g.OrderByDescending(r => r.EarnedDate).First()).ToList();

Lambda expression filtering included related data with Entity Framework

I need to filter only the visibles products from a category, but it's not working.
Category category = db.Categories
.Include(c => c.Products.Where(p => p.IsVisible))
.First(c => c.CategoryID == id);
Error:
The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.
UPDATE
var result = (from c in db.Categories
where c.CategoryID == id
select new
{
CategoryID = c.CategoryID,
Description = c.Description,
Products = (from p in db.Products
where p.IsVisible
&& p.CategoryID == c.CategoryID
orderby p.DateSent descending
select p)
}).FirstOrDefault();
but now i need to cast the anonymousType to Category
Your query doesn't make sense if you want:
the visibles products from a category
If you genuinely want the visible products, try this:
var visibleProducts = db.Categories
.Where(c => c.CategoryID == id)
.Select(c => c.Products.Where(p => p.IsVisible));
Note: untested
Maybe something like:
var category = db.Products.Where(p=>p.IsVisible && p.CategoryID == id).Include("Category").ToList().Select( p=> p.Category).Distinct();
It may not be ideal because of the ToList... but I can see no other way right now.
Maybe you could change the Distinct into a FirstOrDefault()...
var category = db.Products.Where(p=>p.IsVisible && p.CategoryID == id).Include("Category").ToList().FirstOrDefault().Category;
Not tested either...

Categories

Resources