Left Join in Entity Framework - c#

I'm trying convert this SQL to Entity Framework LINQ, but don't working.
My SQL code:
SELECT
s.Id,
s.OriginalPhotoBlobId,
s.PhotoBlobExtension,
ISNULL(s.ProductSkuKey, p.[Key]) as [Key],
p.Name,
ISNULL(sp.Price, 0) as [Price],
sp.PriceList_Id
FROM SKUs s
INNER JOIN Products p on p.Id = s.Product_Id
LEFT JOIN SKUPrices sp on sp.SKU_Id = s.Id
My Entity Framework Code:
var db = this.Context;
var prices = from s in db.SKUs
join p in db.Products on s.Product equals p
join sp in db.SKUPrices on s equals sp.SKU into gj
from spss in gj.DefaultIfEmpty()
select new PriceListItem
{
Id = s.Id,
BlobId = s.OriginalPhotoBlobId,
BlobExtension = s.PhotoBlobExtension,
Key = ((s.ProductSkuKey == null || s.ProductSkuKey.Trim() == string.Empty) ? p.Key : s.ProductSkuKey),
Name = p.Name,
Price = (spss == null ? default(double) : spss.Price),
};

I think you should use navigation properties. Navigation properties are used to navigate through relations in data.

try joining the properties not the classes
var prices = from s in db.SKUs
join p in db.Products on s.Product_Id equals p.Id
join sp in db.SKUPrices on sp.SKU_Id = s.Id into gj
from sp in gj.DefaultIfEmpty()
select new PriceListItem
{
Id = s.Id,
BlobId = s.OriginalPhotoBlobId,
BlobExtension = s.PhotoBlobExtension,
Key = ((s.ProductSkuKey == null || s.ProductSkuKey.Trim() == string.Empty) ? p.Key : s.ProductSkuKey),
Name = p.Name,
Price = (sp == null ? default(double) : sp .Price),
};

Related

Multiple Left Join with Linq and Defaults Values

I'm trying to write a query that contains multiple left joins in linq in a c# .netcore 2.2 application. I've tried writing the query in linq but it is not properly retrieving all the rows. Query I'm trying to convert is as follows.
select ISNULL(b.Id, '00000000-0000-0000-0000-000000000000') as 'Bat Id', p.Id as 'ProductId', p.RP, u.UnitName as 'UnitName', ISNULL(b.QTY,0) as 'BusQty', p.[Name] as 'Product Name'
from Products p left join Bat b
ON p.Id = b.ProductId
left join Units u on p.UOId = u.Id;
linq I have so far
var allProducts = (from p in _db.Products
join s in _db.Bat on p.Id equals s.ProductId into ps
from s in ps.DefaultIfEmpty()
join u in _db.Units on p.UOId equals u.Id
select new
{
BatId = s.Id == null ? Guid.NewGuid() : s.Id,
RP = p.RP,
BusQty = s.QTY == null ? 0 : s.QTY,
ProductName = p.Name,
UnitName = u.UnitName,
ProductId = p.Id,
}).ToList();
You are missing DefaultIfEmpty() on Units, thereby turning it into an inner join
var allProducts = (
from p in _db.Products
join s in _db.Bat on p.Id equals s.ProductId into ps
from s in ps.DefaultIfEmpty()
join u in _db.Units on p.UOId equals u.Id into us
from u in us.DefaultIfEmpty()
select new
{
BatId = s.Id ?? Guid.NewGuid(),
RP = p.RP,
BusQty = s.QTY ?? 0,
ProductName = p.Name,
UnitName = u.UnitName,
ProductId = p.Id,
}).ToList();

LINQ: join multiple Table Column using Linq and find aggregated sum from child table values

I'm using Linq (code-first approach) query to retrieve the data from DB and couldn't able to get similar result while using below linq query:
from msi in db.MainSaleInvoiceTbls
join dsi in db.DetialSaleInvoiceTbls on msi.Id equals dsi.MainSaleInvoiceId
join ca in db.CustomerAccounts on msi.CustomerId equals ca.Id
join cg in db.MiscLists on ca.CustomerGroupId equals cg.Id
where msi.IsActive == true && msi.CompanyId == UniversalInfo.UserCompany.Id && msi.MainSaleInvoiceDataType == MainSaleInvoiceType.SOInvoice
group msi by new { dsi,msi.Date,msi.FinancialVoucher,msi.SaleOrderPrefix,msi.SaleOrderNumber,msi.SalesId,ca.CustomerName,ca.AccountCode,cg.Name }
into mainSaleInvoice
from dx in mainSaleInvoice.DefaultIfEmpty()
// orderby main.Id
select new
{
Date = mainSaleInvoice.Key.Date,
Voucher = mainSaleInvoice.Key.FinancialVoucher,
InvoiceAccount = mainSaleInvoice.Key.AccountCode,
CustomerName = mainSaleInvoice.Key.CustomerName,
CustomerGroup = mainSaleInvoice.Key.Name,
Invoice = mainSaleInvoice.Key.SaleOrderPrefix + mainSaleInvoice.Key.SaleOrderNumber,
PurchaseOrder = mainSaleInvoice.Key.SalesId,
SalesTax = "",
InvoiceAmount = mainSaleInvoice.Sum(x => (Double)(mainSaleInvoice.Key.Quantity * mainSaleInvoice.Key.UnitPrice))
}).ToList()
In linq, i need to get shortdatetimeString() and sum() of (unitprice* quantity) from child table DetialSaleInvoiceTbls
being new in query writing, I don't know where and what I'm doing wrong. Any suggestions would be much appreciated.
var list=from msi in db.MainSaleInvoiceTbls
join dsi in db.DetialSaleInvoiceTbls on msi.Id equals dsi.MainSaleInvoiceId
join ca in db.CustomerAccounts on msi.CustomerId equals ca.Id
join cg in db.MiscLists on ca.CustomerGroupId equals cg.Id into a
where msi.IsActive == true && msi.CompanyId == UniversalInfo.UserCompany.Id
&& msi.MainSaleInvoiceDataType == MainSaleInvoiceType.SOInvoice
from cg in a.DefaultIfEmpty()
select new
{mainSaleInvoice.Date,
mainSaleInvoice.FinancialVoucher,mainSaleInvoice.AccountCode,
mainSaleInvoice.CustomerName,mainSaleInvoice.Name,
mainSaleInvoice.SaleOrderPrefix, mainSaleInvoice.SaleOrderNumber,
mainSaleInvoice.SalesId, }).sum(x=>x. (mainSaleInvoice.Quantity *
mainSaleInvoice.UnitPrice)).groupby msi new
{msi.Date,msi.FinancialVoucher,msi.SaleOrderPrefix,msi.SaleOrderNumber,
msi.SalesId};
Date = mainSaleInvoice.Date;
Voucher = mainSaleInvoice.FinancialVoucher;
InvoiceAccount = mainSaleInvoice.AccountCode;
CustomerName = mainSaleInvoice.CustomerName;
CustomerGroup = mainSaleInvoice.Name;
Invoice = mainSaleInvoice.SaleOrderPrefix +
mainSaleInvoice.SaleOrderNumber;
PurchaseOrder = mainSaleInvoice.SalesId;
SalesTax = "";
InvoiceAmount =list;

Join two linq queries on one key column to get one result set

Here I want to join the out put of the first query(one column) to the result of the 2nd query to get a one result set. How can I merge them.(CONCAT doesn't work as required. eg: var query2 = query.concat(query1);)
var query = (from PP in _db.paymentPlans
join APP in _db.Applications on PP.applicationID equals APP.ApplicationId
join C in _db.Courses on APP.courseID equals C.courseID
where PP.active == true && APP.agentID == agentID
orderby C.courseID ascending
group new {C,PP} by new {C.courseID} into totalRecievable
select new PdPpAppCourseModel
{
courseID = totalRecievable.Key.courseID,
totalAmount = totalRecievable.Sum(x => x.PP.totalAmount)
}).ToList();
var query1=(from PD in _db.paymentDetails
join PP in _db.paymentPlans on PD.paymentPlanID equals PP.paymentPlanID
join APP in _db.Applications on PP.applicationID equals APP.ApplicationId
join C in _db.Courses on APP.courseID equals C.courseID
where PP.active == true && APP.agentID == agentID
orderby C.courseID ascending
group new { C,PD } by new { C.courseID, C.cricosCode, C.courseName } into paymentsCourseWise
select new PdPpAppCourseModel
{
courseID = paymentsCourseWise.Key.courseID,
cricosCode = paymentsCourseWise.Key.cricosCode,
courseName = paymentsCourseWise.Key.courseName,
paidAmount = paymentsCourseWise.Sum(x => x.PD.paidAmount)
}).ToList();
You could join query1 and query like this
var result = (from q1 in query1
join q in query on q1.courseID = q.courseID
select new PdPpAppCourseModel
{
courseID = q1.Key.courseID,
cricosCode = q1.Key.cricosCode,
courseName = q1.Key.courseName,
paidAmount = q1.Sum(x => x.PD.paidAmount),
totalAmount = q.totalAmount
}).ToList();

Convert SqlServer Query to LINQ

I have written the below given query in SQL server 2008:
(SELECT p.postid,
p.title,
p.disabled,
l.locationname
FROM posts p
INNER JOIN categories c
ON p.categoryid = c.categoryid
INNER JOIN users u
ON p.userid = u.userid
INNER JOIN tags t
ON p.tagid = t.tagid
INNER JOIN locations l
ON p.locationid = l.locationid
LEFT JOIN postimages pm
ON p.postid = pm.postid
WHERE p.categoryid = 1
GROUP BY p.postid,
p.title,
p.disabled,
l.locationname)
ORDER BY p.postid DESC
I want to write the above query in LINQ.
I tried a little and able to write the query below:
var objPosts = (from p in _dbcontext.Posts
join us in _dbcontext.Users on p.UserId equals us.UserId
join tag in _dbcontext.Tags on p.TagId equals tag.TagId
join cat in _dbcontext.Categories on p.CategoryId equals cat.CategoryId
join loc in _dbcontext.Locations on p.LocationId equals loc.LocationId
join img in _dbcontext.PostImages on p.PostId equals img.PostId into gj
from postimg in gj.DefaultIfEmpty()
where p.Disabled == false && p.CategoryId == userPost.CategoryId || p.UserId == userPost.UserId || p.TagId == userPost.TagId || p.LocationId == userPost.LocationId
orderby p.PostId descending
select new
{
PostId = p.PostId,
PostTitle = p.Title,
//ImageInfo = postimg.ImagePath,
//ThumbNailInfo = p.ThubNailInfo,
PostShortDescription = p.ShortDescription,
UserId = us.UserId,
UserName = us.Name,
TagId = tag.TagId,
TagTitle = tag.Title,
CategoryId = cat.CategoryId,
CategoryName = cat.CategoryName,
LocationId = loc.LocationId,
LocationName = loc.LocationName
});
I am unable to apply the group by logic in LINQ. Can anyone please convert my SQL to LINQ. Thanks
group new { p, l } by new
{
p.postid,
p.title,
p.disabled,
l.locationname
} into g
orderby g.Key.PostId descending
select new
{
g.key.postid,
g.key.title,
g.key.disabled,
g.key.locationname
}
The missing part in your query is that you are not selecting anything...
You got the joins ok, left outer join ok, predicates (where), ordering, but no projection, and no group by.
Below should get you started:
group p by p.PostId into pg
select new {Post=p, Location=loc};
This would return return a collection of new objects whose properties Post and Location.

Call Method from Linq query

I am using Linq query and call method Like..
oPwd = objDecryptor.DecryptIt((c.Password.ToString())
it will return null value.
Means this will not working.
how I Resolve this.
Thanks..
var q =
from s in db.User
join c in db.EmailAccount on s.UserId equals c.UserId
join d in db.POPSettings
on c.PopSettingId equals d.POPSettingsId
where s.UserId == UserId && c.EmailId == EmailId
select new
{
oUserId = s.UserId,
oUserName = s.Name,
oEmailId = c.EmailId,
oEmailAccId = c.EmailAccId,
oPwd = objDecryptor.DecryptIt(c.Password.ToString()),
oServerName = d.ServerName,
oServerAdd = d.ServerAddress,
oPOPSettingId = d.POPSettingsId,
};
If that is LINQ-to-SQL or Entity Framework. You'll need to break it into steps (as it can't execute that at the DB). For example:
var q = from s in db.User
join c in db.EmailAccount on s.UserId equals c.UserId
join d in db.POPSettings on c.PopSettingId equals d.POPSettingsId
where s.UserId == UserId && c.EmailId == EmailId
select new
{
oUserId = s.UserId,
oUserName = s.Name,
oEmailId = c.EmailId,
oEmailAccId = c.EmailAccId,
oPwd = c.Password,
oServerName = d.ServerName,
oServerAdd = d.ServerAddress,
oPOPSettingId = d.POPSettingsId,
};
then use AsEnumerable() to break "composition" against the back-end store:
var query2 = from row in q.AsEnumerable()
select new
{
row.oUserId,
row.oUserName,
row.oEmailId,
row.oEmailAccId,
oPwd = objDecryptor.DecryptIt(row.oPwd),
row.oServerName,
row.oServerAdd,
row.oPOPSettingId
};
var q = from s in db.User
join c in db.EmailAccount on s.UserId equals c.UserId
join d in db.POPSettings on c.PopSettingId equals d.POPSettingsId
where s.UserId == UserId && c.EmailId == EmailId
select new
{
oUserId = s.UserId,
oUserName = s.Name,
oEmailId = c.EmailId,
oEmailAccId = c.EmailAccId,
oPwd = c.Password,
oServerName = d.ServerName,
oServerAdd = d.ServerAddress,
oPOPSettingId = d.POPSettingsId,
};
foreach (var item in q)
{
item.oPwd = objDecryptor.DecryptIt(row.oPwd),
}
we can use a foreach loop also to update a single property. do not need to select all property in next query.
This has nothing about Linq query. you need to debug method objDecryptor.DecryptIt

Categories