I have this table:
I want to do a linq query where I'll get each property value based on the adminfilterfieldid.
I have this so far:
newDto = from d in DbContext.AdminFilterItems
where d.AdminFilterID == filterId
select new ReservationDto
{
BookingDate = d.Value
};
Now since BookingDate is AdminFilterFieldId is 2, I was hoping I can do something like BookingDate = d.Value.Where(s => s.AdminFilterFieldID = 3) or null in case there is no value for that adminfilterfieldid.
I want to do this for all the fields for that adminfilterid.
Is that achievable somehow with this kind of query or will I need to do multiple queries?
It looks simple enough just another clause in your where.
from d in DbContext.AdminFilterItems
where d.AdminFilterID == filterId
&& d.AdminFilterFieldID = 3
select new ReservationDto
{
BookingDate = d.Value
};
If you need to filter it on multiple values just keep your initial query and run other filters on it then do your projection (select).
var qry = from d in DbContext.AdminFilterItems
where d.AdminFilterID == filterId
// Filter 1
qry.Where(d => d.AdminFilterFieldID = 3).Select(d => new ReservationDto
{
BookingDate = d.Value
});
// Filter 2
qry.Where(d => d.AdminFilterFieldID = 2).Select(d => new ReservationDto
{
BookingDate = d.Value
});
Related
I'm trying to group 3 fields "GameName", "MinBet" and "Time", if data saved on a SQLDb, I just need use WorkScope.GetAll<Game>().GroupBy(s=> new {s.GameName,s.MinBet,s.Time}) then select data to return. But this data saved on Mongo so I cant group like that.
I have try
var query1 = Mongo.GetAll<History>("history").AsQueryable().GroupBy(s=>new GroupBy( s.GameName, s.MinBet, s.Time )).Select(s => new
{
GameId = s.First().GameId,
GameName = s.Key.GameName,
MinBet = s.Key.MinBet,
Time = s.Key.Time,
TotalWin = s.Where(s => s.WinAmount == 0).Sum(s => s.BetAmount),
TotalLose = s.Sum(s => s.WinAmount),
}).ToList();
And
var query=Mongo.GetAll<History>("history")
.Aggregate()
.Group(
s=> new GroupBy
(
s.GameName,
s.MinBet,
s.Time
),
z=> new
{
Key=z.Key,
TotalWin = z.Where(s => s.WinAmount == 0).Sum(s => s.BetAmount),
TotalLose = z.Sum(s => s.WinAmount),
GameId=z.First().Fee
}
)
.Project(s=> new
{
GameId=s.GameId,
GameName=s.Key.GameName,
MinBet=s.Key.MinBet,
Time=s.Key.Time,
TotalWin=s.TotalWin,
TotalLose=s.TotalLose,
}).ToList()
;
It alaways return MongoDB.Bson.BsonSerializationException: No matching creator found.
How can I group it to have right data like SqlDb.
I've been using linq for a little while now but haven't come across this situation anywhere and my google-fu let me down.
Basically I have two data sets which I did not define and now have to use to return data.
class Header
{
string COMPANY_CODE
string REFERENCE_NBR
string REFERENCE_DUPLICATE
...
}
class Line
{
string COMPANY_CODE
string REFERENCE_NBR
string REFERENCE_DUPLICATE
string STOCK_CODE
string DESCRIPTION
...
}
From a database perspective they join like this
select *
from Header
inner join Line
on header.COMPANY_CODE = Line.COMPANY_CODE
and header.REFERENCE_NBR = Line.REFERNCE_NBR
and header.REFERENCE_DUPLICATE = LINE.REFERENCE_DUPLICATE
and have a 1:Many relationship.
I'm implementing a search feature for a listing that is meant to find any Lines that with a value in STOCK_CODE or DESCRIPTION that matches a given search term. I have seen a couple of methods of joining using a linq query but because of the multiple join conditions I'm a bit lost and have not found any examples of what I'm trying to do.
If I were to write the statement I am trying to get in lamda/linq in SQL it would be:
declare #searchtxt nvarchar(max) = 'test'
Select *
from header h
where exists (
select *
from Line l
where
(
l.stock_code like '%'+#searchtxt+'%'
or l.description like '%'+#searchtxt+'%'
)
and h.COMPANY_CODE = l.COMPANY_CODE
and h.REFERENCE_NBR = l.REFERENCE_NBR
and h.REFERENCE_DUPLICATE = l.REFERENCE_DUPLICATE
)
Any help would be appreciated!
Perhaps, this?
var result = header.Where(h =>
Line.Any(l => (l.stock_code.Contains(searchtxt)
|| l.description.Contains(searchtxt))
&& h.COMPANY_CODE == l.COMPANY_CODE
&& h.REFERENCE_NBR == l.REFERENCE_NBR
&& h.REFERENCE_DUPLICATE == l.REFERENCE_DUPLICATE));
This is a traditional LINQ query for better understanding,
string searchtext = "";
var result = (from h in context.Headers
join l in context.Lines on new { h.COMPANY_CODE, h.REFERENCE_DUPLICATE, h.REFERENCE_NBR } equals new { l.COMPANY_CODE, l.REFERENCE_DUPLICATE, l.REFERENCE_NBR }
where l.STOCK_CODE.Contains(searchtext) || l.DESCRIPTION.Contains(searchtext)
select new
{
COMPANY_CODE = h.COMPANY_CODE,
STOCK_CODE = l.STOCK_CODE
//You can select more fields from "h" and "l"
}).ToList();
Edit:
string searchtext = "";
var result = (from h in context.Headers
join l in context.Lines on new { h.COMPANY_CODE, h.REFERENCE_DUPLICATE, h.REFERENCE_NBR } equals new { l.COMPANY_CODE, l.REFERENCE_DUPLICATE, l.REFERENCE_NBR }
where l.STOCK_CODE.Contains(searchtext) || l.DESCRIPTION.Contains(searchtext)
select h
)
.GroupBy(x => new { x.COMPANY_CODE, x.REFERENCE_DUPLICATE, x.REFERENCE_NBR })
.Select(x => x.First())
.ToList();
db.Header.Join(
db.Line,
h => new { h.COMPANY_CODE, h.REFERENCE_NBR, h.REFERENCE_DUPLICATE },
l => new { l.COMPANY_CODE, l.REFERENCE_NBR, l.REFERENCE_DUPLICATE },
(h, l) => new
{
Header_COMPANY_CODE = h.COMPANY_CODE,
Header_REFERENCE_NBR = h.REFERENCE_NBR,
Header_REFERENCE_DUPLICATE = h.REFERENCE_DUPLICATE,
Line_Company_Code = l.COMPANY_CODE,
Line_REFERENCE_NBR = l.REFERENCE_NBR,
Line_REFERENCE_DUPLICATE = l.REFERENCE_DUPLICATE,
Line_STOCK_CODE = l.STOCK_CODE,
Line_DESCRIPTION = l.DESCRIPTION
}
)
.Where(w => w.Line_STOCK_CODE.Contains(searchText) || w.Line_DESCRIPTION.Contains(searchText))
.ToList();
I am developing a query to grab and join some SQL tables in C# and am having some trouble with grouping and enumerables within the dataset. My query is below. This gives me the data in the format I'm looking for, but it takes way too long when I try to add the enumerated list as indicated below. When I look under the hood I can see it is executing way too many SQL queries. I'd like to get it to just one. Using LinqPad:
void Main()
{
var nightlyRuns = (from a in LoadTestSummaries
join b in LoadTestTestSummaryData
on a.LoadTestRunId equals b.LoadTestRunId
where a.TargetStack == "LoadEnv" &&
a.TestGuid != null &&
a.StartTime != null &&
a.LoadTestRunId != null
orderby a.StartTime
group new {a, b} by new
{
a.TestGuid,
a.Name,
a.Description,
a.StartTime,
a.Duration,
a.NumAgents,
a.NumHosts,
a.PassFail,
a.ResultsFilePath,
a.Splunk
}
into g
let scenarioStart = g.Min(s => s.a.StartTime) ?? g.Min(s => s.a.DateCreated)
let testCases = g.Select(s => s.b)
orderby scenarioStart
select new
{
TestGuid = g.Key.TestGuid,
ScenarioRun = new
{
Name = g.Key.Name,
Description = g.Key.Description,
StartTime = scenarioStart,
Duration = g.Key.Duration,
NumAgents = g.Key.NumAgents,
NumHosts = g.Key.NumHosts,
Result = g.Key.PassFail,
ResultsFilePath = g.Key.ResultsFilePath,
SplunkLink = g.Key.Splunk,
// PROBLEM: Causes too many queries:
TestRuns = from t in testCases select t.TestCaseId
}
}).ToLookup(g => g.TestGuid, g => g.ScenarioRun);
nightlyRuns["ba593f66-695f-4fd1-99c3-71253a2e4981"].Dump();
}
The "TestRuns" line is causing the excessive queries. Any idea what I am doing wrong here?
Thanks for any insight.
Tough answer to test but I think we can avoid the grouping and multiple queries with something like this: (https://msdn.microsoft.com/en-us/library/bb311040.aspx)
var nightlyRuns = (from a in LoadTestSummaries
join b in LoadTestTestSummaryData
on a.LoadTestRunId equals b.LoadTestRunId
where a.TargetStack == "LoadEnv" &&
a.TestGuid != null &&
a.StartTime != null &&
a.LoadTestRunId != null
into testGroup
select new
{
TestGuid = a.TestGuid,
ScenarioRun = new
{
Name = a.TestGuid,
Description = a.Description,
StartTime = a.StartTime ?? a.DateCreated,
Duration = a.Duration,
NumAgents = g.Key.NumAgents,
NumHosts = a.NumHosts,
Result = a.PassFail,
ResultsFilePath = a.ResultsFilePath,
SplunkLink = a.Splunk,
// PROBLEM: Causes too many queries:
TestRuns =testGroup
}
}).OrderBy(x=>x.StartTime).ToLookup(x => x.TestGuid, x => x.ScenarioRun);
nightlyRuns["ba593f66-695f-4fd1-99c3-71253a2e4981"].Dump();
I need to sum elements of same type starting from 2 LINQ queries.
Below is my code:
var query1 = from d in _contextProvider.Context.Documents
where d.TransportId == transportId
group d by d.Type
into dg
select new { DocumentType = dg.Key.ToString(), DocumentCount = dg.Count() };
var query2 = from n in _contextProvider.Context.NotificationDocuments
where n.TransportId == transportId
group n by n.TransportId
into nd
select new { DocumentType = "Notification", DocumentCount = nd.Count() };
var query_collapsed = query1.Union(query2)
.GroupBy(p => new { DocumentType = p.DocumentType })
.Select(g => new DocumentCounters() { DocumentType = g.Key.DocumentType, DocumentCount = g.Sum(p => p.DocumentCount) });
Example: below let's analyse values for DocumentType equals to Notification.
Values of query1:
Values of query2:
The collapsed query :
That's correct: 1 + 2 = 3
The problem: I noticed that whenever the count for Notification in query1 is equals to the count for Notification in query2, then the sum is not performed.
Example:
2 + 2 = 2
or
3 + 3 = 3
Any ideas ?
LINQ Union will remove duplicate entries. If you want to merge the two sequences you can use Concat like so:
var query_collapsed = query1.Concat(query2)
.GroupBy(p => new { DocumentType = p.DocumentType })
.Select(g => new DocumentCounters() { DocumentType = g.Key.DocumentType, DocumentCount = g.Sum(p => p.DocumentCount) });
I spend a few hours trying to translate simple SQL to lambda LINQ
SELECT ID, AVG(Score) FROM myTable
GROUP BY ID
Any idea?
from t in myTable
group t by new {
t.ID
} into g
select new {
Average = g.Average(p => p.Score),
g.Key.ID
}
or Lambda
myTable.GroupBy(t => new {ID = t.ID})
.Select (g => new {
Average = g.Average (p => p.Score),
ID = g.Key.ID
})
The equivalent in Linq-to-Objects would be something like the below.
var results = from row in myTable
group row by row.Id into rows
select new
{
Id = rows.Key,
AverageScore = rows.Average(row => row.Score)
};
It's only slightly different for an ORM like entity framework. Namely, you would need to go through the data context or an appropriate DbSet/ObjectSet.
var _result = from a in myTable
group a by a.ID into g
select new
{
ID = g.Key.ID,
AverageResult = g.Average(x => x.Score)
}