Hi I am running one Linq query to join three tables. below is the query...
answerText = ds.Tables[0];
questionAvg = ds.Tables[1];
interviews = ds.Tables[2];
var data = from at in answerText.AsEnumerable()
join qa in questionAvg.AsEnumerable() on at.Field<int>("ID") equals qa.Field<int>("DealerID")
join inter in interviews.AsEnumerable() on at.Field<int>("ID") equals inter.Field<int>("DealerID")
select new
{
DealerID = at.Field<int>("ID"),
DealerName = at.Field<string>("Name"),
AnswerText1 = at.Field<int?>("12"),
AnswerText2 = at.Field<int?>("8"),
AnswerText3 = at.Field<int?>("4"),
AnswerText4 = at.Field<int?>("0"),
AnswerText5 = at.Field<int?>("-4"),
Rank = qa.Field<Int64?>("Rank"),
Average = qa.Field<decimal?>("Average"),
N = inter.Field<int?>("N")
};
now sometimes answerText datatable will only have column 12 and 8.., so it is missing columns 4 0 -4. how should i avoid that column check in above query and just provide 0 there.
I'm not 100% sure what you're asking about, but I assumed you need AnswerText properties to be int not int?. And they should be set to 0 when item is not present. You can use ?? operator:
var data = from at in answerText.AsEnumerable()
join qa in questionAvg.AsEnumerable() on at.Field<int>("ID") equals qa.Field<int>("DealerID")
join inter in interviews.AsEnumerable() on at.Field<int>("ID") equals inter.Field<int>("DealerID")
select new
{
DealerID = at.Field<int>("ID"),
DealerName = at.Field<string>("Name"),
AnswerText1 = at.Field<int?>("12") ?? 0,
AnswerText2 = at.Field<int?>("8") ?? 0,
AnswerText3 = at.Field<int?>("4") ?? 0,
AnswerText4 = at.Field<int?>("0") ?? 0,
AnswerText5 = at.Field<int?>("-4") ?? 0,
Rank = qa.Field<Int64?>("Rank"),
Average = qa.Field<decimal?>("Average"),
N = inter.Field<int?>("N")
};
Related
I have this code, where I'm union data from 2 tables
var test =
(from table1 in db.Products
select new UnionTable()
{
ProductNumber = table1.ProductNumber,
OrderNumber = 0,
Cost = table1.Cost,
Price = table1.Price,
Name = table1.Name,
Amount = 0,
Inventory = table1.Inventory
}).Union
(from table2 in db.OrderItems
select new UnionTable()
{
ProductNumber = table2.ProductNumber,
OrderNumber = table2.OrderNumber,
Cost = 0,
Price = 0,
Name = string.Empty,
Amount = table2.Amount,
Inventory = 0
});
the output is
what I'm trying to do, is to fill the missing places with data. for example in name, I want all places where Product Number is 1, to be almond.
in price where Product Number is 1, all columns to be 10
How can I fix this?
You could always try something like this:
var test =
(from table1 in db.Products
select new UnionTable()
{
ProductNumber = table1.ProductNumber,
OrderNumber = 0,
Cost = table1.Cost,
Price = table1.Price,
Name = table1.Name,
Amount = 0,
Inventory = table1.Inventory
}).Union
(from table2 in db.OrderItems
select new UnionTable()
{
ProductNumber = table2.ProductNumber,
OrderNumber = table2.OrderNumber,
Cost = 0,
Price = table1.Price == 0 && table1.ProductNumber == 1 ? 10 : table1.Price,
Name = table1.Name == string.Empty && table1.ProductNumber == 1 ? "Almond" : table1.Name,
Amount = table2.Amount,
Inventory = 0
});
Not the most clean solution but it should do the job
I did a lot of research and read some of the similar questions and answers, but still have no clue how to write the EF Core code to create the following SQL server query. Can someone help. I have seen tutorials explaining how to join 2 tables with LEFT JOIN, but couldn't find any that includes 3 or more tables.
SELECT std.DocID, std.ServiceCode,
CASE std.Description
WHEN 'Car Wash'
THEN 'Misc'
ELSE std.Description
END AS 'Description',
std.StandardRate, std.StandardHours,
det.ParticipantCount, det.TotalHours, det.TotalFees
FROM StandardServices std
INNER JOIN Sorted srt
ON std.ServiceCode = srt.ServiceCode
LEFT OUTER JOIN ServiceDetails det
ON det.ParentRecordUNID='00000000-0000-0000-0000-000000000000' AND det.ServiceTypeUNID=std.DocID
WHERE std.IsDeleted='N' AND std.TopService = 'Y'
ORDER BY srt.SortOrder
Following is what came close to the above (I have replaced some text for privacy concerns, so may not exactly match). But for some reasons, it selects all of the columns than what is mentioned. Also, it adds a (SELECT 1) at the end.
var results=await (from sso in context.StandardServices
join mos in context.Sorted on sso.ServiceCode equals mos.ServiceCode
join mad in context.ServiceDetails
on new { key1 = sso.DocID, key2 = parentId } equals new { key1 = (Guid)mad.ServiceTypeUnid, key2 = mad.ParentRecordUnid }
into jointable
where sso.IsDeleted == "N" && sso.TopService =="Y"
orderby mos.SortOrder
from mad1 in jointable.DefaultIfEmpty()
select new ServiceRowDetails()
{
DocID = mad1.DocID,
ParentRecordUnid = mad1.ParentRecordUnid,
ServiceTypeUnid = sso.DocID,
ServiceType = sso.Description,
ParticipantCount = mad1.ParticipantCount ?? 0,
StandardFees = sso.StandardRate ?? 0,
StandardHours = sso.StandardHours ?? 0,
TotalFees = mad1.TotalFees ?? 0,
TotalHours = mad1.TotalHours ?? 0
}).ToListAsync();
UPDATE: Made changes as #IvanStoev commented below and it worked just fine.
var results=await (from sso in context.StandardServices
join mos in context.Sorted on sso.ServiceCode equals mos.ServiceCode
join mad in context.ServiceDetails
on new { key1 = sso.DocID, key2 = parentId } equals new { key1 = (Guid)mad.ServiceTypeUnid, key2 = mad.ParentRecordUnid }
into jointable
from mad1 in jointable.DefaultIfEmpty()
where sso.IsDeleted == "N" && sso.TopService =="Y"
orderby mos.SortOrder
select new ServiceRowDetails()
{
DocID = mad1.DocID,
ParentRecordUnid = mad1.ParentRecordUnid,
ServiceTypeUnid = sso.DocID,
ServiceType = sso.Description,
ParticipantCount = mad1.ParticipantCount ?? 0,
StandardFees = sso.StandardRate ?? 0,
StandardHours = sso.StandardHours ?? 0,
TotalFees = mad1.TotalFees ?? 0,
TotalHours = mad1.TotalHours ?? 0
}).ToListAsync();
below I have listed a linq query that works properly in my asp.net.mvc web app.
In addition I would like to group over 'allowance.ParameterId' in order to get the group sum for 'allowance.Freight (instead of multiple records for the given key).
var query = from ara in aras
join company in companies on ara.Id equals company.ARAId
join wasteWater in wasteWaters on company.Id equals wasteWater.CompanyId
join allowance in allowances on wasteWater.Id equals allowance.WasteWaterID
join parameter in parameters on allowance.ParameterId equals parameter.Id into JoinedParameterAllowance
from parameter in JoinedParameterAllowance.DefaultIfEmpty()
where company.Activ == true && company.End == null && company.Template == false
&& wasteWater.End == null
select new FreightSummaryViewModel
{
AraName = ara.Name,
AraId = ara.Id,
AllowedParameter = parameter.Name,
AllowedFreight = allowance.Freight
};
I have tried to insert 'group ...' but failed to get it right.
Could someone help me please to set up the proper syntax?
Thank you in advance, Manu
I have little idea about relations in your database, so I improvised...
// Some dummy data to play with
var aras = Enumerable.Range(0, 5).Select(i => new { Id = i, Name = "Ara" + i });
var companies = Enumerable.Range(0, 15).Select(i => new { Id = i, ARAId = i % 5, Activ = true, End = (DateTime?)null, Template = false });
var wasteWaters = Enumerable.Range(0, 35).Select(i => new { Id = i, CompanyId = i / 15, End = (DateTime?)null });
var allowances = Enumerable.Range(0, 70).Select(i => new { Id = i, WasteWaterID = i, ParameterId = i % 4, Freight = i * 1000 });
var parameters = Enumerable.Range(0, 4).Select(i => new { Id = i, Name = "Parameter" + i });
And this is what I believe you looked for:
var query =
from ara in aras
join company in companies on ara.Id equals company.ARAId
join wasteWater in wasteWaters on company.Id equals wasteWater.CompanyId
join allowance in allowances on wasteWater.Id equals allowance.WasteWaterID
join parameter in parameters on allowance.ParameterId equals parameter.Id
into JoinedParameterAllowance
// from parameter in JoinedParameterAllowance.DefaultIfEmpty()
where true
&& company.Activ == true
&& company.End == null
&& company.Template == false
&& wasteWater.End == null
group allowance by new
{
AraName = ara.Name,
AraId = ara.Id,
ParameterId = allowance.ParameterId
} into myGroup
select new //FreightSummaryViewModel
{
AraName = myGroup.Key.AraName,
AraId = myGroup.Key.AraId,
AllowedParameter = myGroup.Key.ParameterId,
AllowedFreight = myGroup.Sum(g => g.Freight)
};
I am using the below Inner Join to retrive the Data between the two tables, but all data is not getting populated. I tried implementing Outer join by connecting using CCY1== CCY1 and PCODE == PCODE, but no luck.
var q = from g1 in TableCCY1.AsEnumerable()
join g2 in TableCCY2.AsEnumerable()
on g1.Field<string>("CCY1") equals g2.Field<string>("CCY1")
where g1.Field<string>("PCODE") == g2.Field<string>("PCODE")
select new
{
g1currency = g1.Field<string>("CCY1"),
g2currency = g2.Field<string>("CCY1"),
g1code = g1.Field<string>("PCODE"),
g2code = g2.Field<string>("PCODE"),
g1Amt1 = g1.Field<string>("AMT1"),
g2Amt2 = g2.Field<string>("AMT2")
};
Thanks for your help.
For left join you can use this approuch: http://msdn.microsoft.com/en-us/library/vstudio/bb397895.aspx
The code should be:
var q = from g1 in TableCCY1
join g2 in TableCCY2 on g1.CCY1 equals g2.CCY1 && g1.PCODE equals g2.PCODE into TableCCY3
from g3 in TableCCY3.DefaultIfEmpty()
select new
{
g1currency = g1.CCY1,
g2currency = (g3 == null ? String.Empty : g3.CCY1),
g1code = g1.PCODE,
g2code = (g3 == null ? String.Empty : g3.PCODE),
g1Amt1 = g1.AMT1,
g2Amt2 = (g3 == null ? 0 : g3.AMT2)
};
It looks like you just want to union/concat the two tables into one and then just group on those two columns. You're not logically joining the two tables. That actually makes it much easier.
var q = from row in TableCCY1.AsEnumerable().Concat(TableCCY2.AsEnumerable())
group row by new
{
CCY1 = row.Field<string>("CCY1"),
PCode = row.Field<string>("PCODE")
} into matches
select new
{
CCY1 = matches.Key.CCY1,
PCODE = matches.Key.PCode,
Sum = matches.Sum(match => match.Field<decimal?>("AMT2")),
};
I'm trying to transform the SQL Query below into Linq to SQL
select Categorias.IdCategoria, Categorias.Nome, SUM(lancamentos.valor)
from lancamentos
left outer join Categorias on Lancamentos.IdCategoria = Categorias.IdCategoria
where Month(DataLancamento) = 11
and Credito = 1
and Lancamentos.Ocultar = 0
group by Categorias.IdCategoria, Categorias.Nome
This is what I've done
from lancamento in Lancamentos
where lancamento.Credito == true
&& lancamento.Ocultar == false
&& lancamento.DataLancamento.Month == 10
join categoria in Categorias on lancamento.IdCategoria equals categoria.IdCategoria into temp
from lancamentoJoinCategoria in temp.DefaultIfEmpty()
group lancamentoJoinCategoria by new { lancamentoJoinCategoria.IdCategoria, lancamentoJoinCategoria.Nome } into x
select new {
IdCategoria = (int?)x.Key.IdCategoria
, Nome = x.Key.Nome
}
How do I add the SUM(lancamentos.valor) to the linq to sql above ?
It will be:
(from lancamento in Lancamentos
join categoria in Categorias on lancamento.IdCategoria equals categoria.IdCategoria into temp
from lancamentoJoinCategoria in temp.DefaultIfEmpty()
where lancamento.Credito == true
&& lancamento.Ocultar == false
&& lancamento.DataLancamento.Month == 10
group lancamento by new { lancamentoJoinCategoria.IdCategoria, lancamentoJoinCategoria.Nome } into x
select new
{
IdCategoria = (int?)x.Key.IdCategoria,
Nome = x.Key.Nome,
sumValor = x.Sum(a=>a.valor)
});
You use the .Sum() method.
Eg;
Public Sub LinqToSqlCount03()
Dim q = (From o In db.Orders _
Select o.Freight).Sum()
Console.WriteLine(q)
End Sub
according to MSDN there is no query expression equivalent to the Sum() operation.
I provided a little sample how you could use the Method Syntax of Sum() in a query.
Some query operations, such as Count
or Max, have no equivalent query
expression clause and must therefore
be expressed as a method call. Method
syntax can be combined with query
syntax in various ways. For more
information, see LINQ Query Syntax versus Method Syntax (C#).
var example = new[]
{
new { Count = 1, Name = "a" }, new { Count = 2, Name = "b" },
new { Count = 2, Name = "c" }, new { Count = 2, Name = "c" }
};
var result = from x in example
select new
{
x.Name,
Sum = (from y in example
where y.Count.Equals(2)
&& y.Name==x.Name
select y.Count).Sum()
};
var distinct = result.Distinct().ToList();