I am working on a composite ranking website. I am trying to query the most recent ranking and the previous ranking side by side.
This query works great in SSMS, but I am unable to make this work in my C# code:
SELECT r.Name, l.RankValue AS currentValue, l.RankDT as CurrentDT, p.RankValue AS prevVal, p.RankDT AS prevDate
FROM RankLookupTB L
JOIN RankingsTB R ON L.RankID = R.RankID
FULL JOIN (SELECT rankid, rankvalue, RankDT FROM RankLookupTB WHERE Obselete = 1 and TeamID = 356) AS P ON l.RankID = p.RankID
WHERE l.TeamID = 356 and Obselete = 0
ORDER BY r.Name
Here is what I have in my Program:
var ranks = from r in _context.RankLookupTbs
where r.TeamId == id && r.Obselete == false
join s in _context.RankingsTbs on r.RankId equals s.RankId
join t in _context.RankLookupTbs on new { id = r.RankId, obsolete = r.Obselete } equals new { id = t.RankId, obsolete = true }
select new { Name = s.Name, CurrentValue = r.RankValue, CurrentDT = r.RankDt, PastValue = t.RankValue, PastDT = t.RankDt };
I am sure that I am not far away from the answer. The join seems to be the problem because I am getting everything in the result set.
Lastly, I downloaded LINQPad, but it is not giving me anything at all.
Thanks for all insights
Related
I have been trying to convert this SQL statement into a linq as i am trying to move the functionality into a program.
Here is the SQL statement
SELECT cust.sg_group_name AS customer,
(SELECT Sum(du.used_space)
FROM sg_groups AS clnt
LEFT JOIN client_disk_usage AS du
ON clnt.sg_group_id = du.sg_group_id
AND clnt.group_role_id = 3
WHERE clnt.parent_group_id = cust.sg_group_id
AND du.day_of_month = 15
AND du.month_of_year = 05
AND du.used_space_year = 2016) AS disk_usage
FROM sg_groups AS cust
WHERE cust.group_role_id = 2
ORDER BY cust.sg_group_name
Essentially the output is just a list with two columns
customer disk_usage
Customer1 136401537652
Customer2 42208008210
If possible i just want to convert this to a linq statement. I have tried putting the query into LinqPad, but it doesn't seem to want to convert from SQL to Linq (just comes up with a blank white page). I have had a crack at the query myself, but i either get something that doesn't work altogether, or an incorrect number of results.
If anyone has any suggestions that would be great!
disk_usage(Sub Query) is a bit Complicated Part. Converted over here. Try this out
var CoreList = (from clnt in EntityName.sg_groups
join du in EntityName.client_disk_usage
on new { GrpId = clnt.sg_group_id, RoleId = clnt.group_role_id } equals new { GrpId = du.sg_group_id, RoleId = 3 } into LJ
from RT in LJ.DefaultIfEmpty()
where du.day_of_month == 15 && du.month_of_year == 05 && du.used_space_year == 2016
select new {clnt, du, RT}
).ToList();
var CoreListSet = CoreList.Select(i=> new YourEntityClass
{
//Fetch the ParentGroupId & UsedSpace
}).ToList();
var CoreListComplete = (from cl in CoreListSet
join cust in EntityName.sg_groups
on cust.sg_group_id equals cl.parent_group_id).ToList();
Now get the sum of CoreListComplete & just implement the base Select Query in Linq!
Apologies for the delayed response. I've marked #Anil answer up as this is the one that helped me find the answer. You solution did work #Sathish but it can be accomplished in a single command. Here is my final solution. Many thanks for your help!
storeGridUsage = (
from cust in db.sg_groups
from client in db.sg_groups
join du in db.client_disk_usage on client.SG_GROUP_ID equals du.SG_GROUP_ID
where client.GROUP_ROLE_ID == 3
where client.PARENT_GROUP_ID == cust.SG_GROUP_ID && du.DAY_OF_MONTH == day && du.MONTH_OF_YEAR == month && du.USED_SPACE_YEAR == year
where cust.GROUP_ROLE_ID == 2
orderby cust.SG_GROUP_NAME
group new {cust, du} by cust.SG_GROUP_NAME
into g
select new StoreGridUsage
{
CustomerName = g.Key,
DiskUsageInBytes = g.Sum(o => o.du.USED_SPACE)
}).ToList();
I'm trying to retrieve some records from database along with a count, with LINQ.
DataTable dtByRecipe = (from tbrp in context.tblRecipeParents
join tbrc in context.tblRecipeChilds on tbrp.RecipeParentID equals tbrc.RecipeParentID
join tbp in context.tblProducts on tbrc.ProductID equals tbp.ProductID
join tbps in context.tblProductSales.AsEnumerable()
on tbp.ProductID equals tbps.ProductID
join tbs in context.tblSales.AsEnumerable()
on tbps.ProductSalesID equals tbs.ProductSalesID select new
{
tbrp.Recipe,
tbp.ProductID,
tbps.ProductSalesID,
tbrp.Yield,
Product = tbp.ProductCode + " - " + tbp.ProductDescription,
ProductYield = tbrp.Yield,
TotalYield = "XXX",
Cost = "YYY"
}).AsEnumerable()
.Select(item => new {
item.Recipe,
Count = GetCount(item.ProductID, item.ProductSalesID, context),
item.Yield,
Product = item.Product,
ProductYield = item.ProductYield,
TotalYield = "XXX",
Cost = "YYY"
}).OrderBy(o => o.Recipe).ToDataTable();
private int GetCount ( int ProductID, int ProductSalesID, MTBARKER_DBEntities context )
{
int query = ( from tbps in context.tblProductSales
join tbp in context.tblProducts on tbps.ProductID equals tbp.ProductID
join tbs in context.tblSales
on tbps.ProductSalesID equals tbs.ProductSalesID
where tbp.ProductID == ProductID && tbps.ProductSalesID == ProductSalesID
select tbs ).Count();
return query;
}
In above query I get the expected result but since there are around 10K records in the database it consumes a lot of time to produce the result. The issue is with the following approach I have used to get the count.
Count = GetCount(item.ProductID, item.ProductSalesID, context),
Is there any productive way that I could prevent this issue?
Well Stored Procedures is best choice for performance.Use Stored Procedures in the Entity Framework for selection and for reporting.
I have an user table called zeekuser in which I am storing Time Zone information related to user. while retrieving I using below code,
var v = (from s in dc.UserWebSites
join zk in dc.ZeekUsers on s.aspnet_User.UserId equals zk.UserId
where s.aspnet_User.LoweredUserName.Equals(strUsername.ToLower())
select new UserWebSiteInfo
{
CreateDt = TimeZoneInfo.ConvertTimeFromUtc(s.CreateDt, TimeZoneInfo.FindSystemTimeZoneById(zk.TimeZoneID)),
LastUpdateDt = TimeZoneInfo.ConvertTimeFromUtc(s.LastUpdate, TimeZoneInfo.FindSystemTimeZoneById(zk.TimeZoneID)),
LogoImage = s.LogoImage,
Nickname = s.Nickname,
Title1 = s.Title1,
Title2 = s.Title2,
SiteID = s.SiteID.ToString(),
TemplateID = s.TemplateID.ToString(),
TemplateName = s.WebSiteTemplate.ThemeName,
IsActive = s.IsActive,
IsRedirect = s.IsRedirect,
RedirectURL = s.RedirectURL,
UPID = s.UPID.ToString(),
UserId = s.aspnet_User.UserId.ToString(),
Username = s.aspnet_User.UserName,
UserProductName = s.UserProductDetail.Nickname,
PageCount = s.UserWebSitePages.Count(),
AuthorName = s.AuthorName,
AuthorURL = s.AuthorURL
}).OrderByDescending(y => y.LastUpdateDt);
info = v.ToList();
but I am getting below error
Method 'System.TimeZoneInfo FindSystemTimeZoneById(System.String)' has no supported translation to SQL.
Each different user can have different time zones. How can I resolve this?
I doubt that you can do that within the query that's sent to SQL Server. Instead, use AsEnumerable to change context to perform the final step on the .NET side:
var query = from s in dc.UserWebSites
join zk in dc.ZeekUsers on s.aspnet_User.UserId equals zk.UserId
where s.aspnet_User.LoweredUserName.Equals(strUsername.ToLower())
orderby s.LastUpdate descending
select new { Site = s, ZoneId = zk.TimeZoneID };
// Do the rest of the query in-process, so we can use time zones.
var results = (from pair in query.AsEnumerable()
let site = pair.Site
let zone = TimeZoneInfo.FindSystemTimeZoneById(pair.ZoneId)
select new UserWebSiteInfo {
// Select all your properties here
}).ToList();
This is assuming that there's not much more information in UserWebSites than you'll be using to construct the UserWebSiteInfo; if there is a load of information which is irrelevant, you should select the relevant parts explicitly in your initial db-side query.
I have 2 records in tblMaterials and zero record in tblMaterialTenderGroups
But when I fetch the data to gridview it shows me the two records, and the join doesn't work
public List<tblMaterial> ShowPresentMaterialInGroup()
{
List<tblMaterial> q = (from i in dbconnect.tblMaterials.AsEnumerable()
join b in dbconnect.tblMaterialTenderGroups on i.materialId equals b.materialId
where b.MaterialGroupId == _materialGroupId
select new tblMaterial()
{
existAmout = i.existAmout,
materialId = i.materialId,
name = i.name,
needAmount = i.needAmount,
requestAmount = i.requestAmount,
unit = i.unit,
requestId = i.requestId
}).ToList();
return q;
}
Can you please try this
List<tblMaterial> q = from i in dbconnect.tblMaterials
join b in dbconnect.tblMaterialTenderGroups on i.materialId equals b.materialId
select new { existAmout = i.existAmout,
materialId = i.materialId,
name = i.name,
needAmount = i.needAmount,
requestAmount = i.requestAmount,
unit = i.unit,
requestId = i.requestId}.ToList();
May be using returning the two records..
I read something here
Using AsEnumerable will break off the query and do the "outside part"
as linq-to-objects rather than Linq-to-SQL. Effectively, you're
running a "select * from ..." for both your tables and then doing the
joins, where clause filter, ordering, and projection client-side.
I'm trying to rewrite a SQL query in LINQ to Entities. I'm using LINQPad with a typed datacontext from my own assembly to test things out.
The SQL query I'm trying to rewrite:
SELECT DISTINCT variantID AS setID, option_value AS name, option_value_description AS description, sort_order as sortOrder
FROM all_products_option_names AS lst
WHERE lst.optionID=14 AND lst.productID IN (SELECT productID FROM all_products_option_names
WHERE optionID=7 AND option_value IN (SELECT name FROM brands
WHERE brandID=1))
ORDER BY sortOrder;
The LINQ to Entities query I've come up with so far (which doesn't work due to a timeout error):
from a in all_products_option_names
where a.optionID == 14 && all_products_option_names.Any(x => x.productID == a.productID && x.optionID == 7 && brands.Any(y => y.name == x.option_value && y.brandID == 1))
select new
{
id = a.variantID,
name = a.option_value,
description = a.option_value_description,
sortOrder = a.sort_order,
}
This is the error I get when I run the above query: An error occurred while executing the command definition. See the inner exception for details.
And the inner exception is: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Edit:
I use MySQL and probably that's why LINQPad doesn't show me the generated SQL.
The SQL version doesn't time out.
Edit 2:
I solved the problem by completely changing the query, so this question is irrelevant now.
I marked Steven's response as the correct one, because he was closest to what i was trying to achieve and his response gave me the idea which led me to the solution.
Try this:
var brandNames =
from brand in db.Brands
where brand.ID == 1
select name;
var brandProductNames =
from p in db.all_products_option_names
where p.optionID == 7
where brandNames.Contains(p.option_value)
select p.productId;
var results =
from p in db.all_products_option_names
where p.optionID == 14
where brandProductNames.Contains(p.productId)
select new
{
setID = p.variantID,
name = p.option_value,
description = p.option_value_description,
sortOrder = p.sort_order
};
I would recommend doing joins rather than sub-select's as you have them. Sub-selects are not very efficient when you look at performance, it's like having loops inside of loops when you code , not a good idea. This could actually cause that timeout your getting if your database is running slowly even thou that looks like a simple query.
I would try using joins with a distinct at the end like this:
var results =
(from p in db.all_products_option_names
join p2 in db.all_products_option_names on p.productId equals p2.productId
join b in db.Brands on p2.option_value equals b.name
where p.optionID == 14
where p2.optionID == 7
where b.BrandID == 1
select new
{
setID = p.variantID,
name = p.option_value,
description = p.option_value_description,
sortOrder = p.sort_order
}).Distinct();
Or you could try using joins with the into and with an any like so
var results =
from p in db.all_products_option_names
join p2 in (from p3 in db.all_products_option_names.Where(x => x.optionId == 7)
join b in db.Brands.Where(x => x.BrandID == 1) on p3.option_value equals b.name
select p3) into pg
where p.optionID == 14
where pg.Any()
select new
{
setID = p.variantID,
name = p.option_value,
description = p.option_value_description,
sortOrder = p.sort_order
};