I'm having a problem when filtering my EF Core results. My query is plain and simple, yet the results are not what I expected. The code shown here are the queries I've tried so far, yet the items that I don't want to be shown are still included in the results.
Then items with P8, DG, DJ, DH, DM should not be included in the query but when I run the app document types with P8, DG, DJ, DH, DM is still included.
#foreach (var cmdm in ViewBag.BSID_UNPAID)
{
<tr>
<td>#cmdm.BLART</td>
<td>#cmdm.KUNNR</td>
<td>#cmdm.BUDAT</td>
<td></td>
<td>#cmdm.SGTXT</td>
<td>#cmdm.DMBTR</td>
</tr>
}
First code I've tried
ViewBag.BSID_UNPAID = _context.BSIDs.Where(i =>
(i.UMSKZ == "" && i.BLART != "P8") ||
(i.UMSKZ == "" && i.BLART != "DG") ||
(i.UMSKZ == "" && i.BLART != "DJ") ||
(i.UMSKZ == "" && i.BLART != "DH") ||
(i.UMSKZ == "" && i.BLART != "DM")).OrderByDescending(e => e.ZFBDT);
Second code I've tried
ViewBag.BSID_UNPAID = _context.BSIDs.Where(a =>
a.UMSKZ == "" &&
(a.BLART != "P8" ||
a.BLART != "DG" ||
a.BLART != "DJ" ||
a.BLART != "DH" ||
a.BLART != "DM")).OrderByDescending(e => e.ZFBDT);
Items with DM Doc Type should not be included, but in the screenshot above, they are still included.
I hope someone can help me figure out which part of the code I'm wrong.
As #Jeremy Lakeman said in comment, true Or false always return true. So, the second part is always true.
(a.BLART != "P8" ||
a.BLART != "DG" ||
a.BLART != "DJ" ||
a.BLART != "DH" ||
a.BLART != "DM")
And the second query equals
ViewBag.BSID_UNPAID = _context.BSIDs.Where(a => a.UMSKZ == "").OrderByDescending(e => e.ZFBDT);
Then items with P8, DG, DJ, DH, DM should not be included in the query
So, all these conditions should be connected by logical AND operator.
ViewBag.BSID_UNPAID = _context.BSIDs.Where(a =>
a.UMSKZ == "" &&
a.BLART != "P8" &&
a.BLART != "DG" &&
a.BLART != "DJ" &&
a.BLART != "DH" &&
a.BLART != "DM").OrderByDescending(e => e.ZFBDT);
I've been working on this for hours today and feel like there is an easy way to do this but I am unable to make it work by anything but brute force.
I have an entity in my application that serves as a Mapping between two objects, based on 5 filters. The goal is to find the record with the most specific match to the filters.
Right now, I am manually brute forcing 2^5 queries to get the most specific row, but feel like there has to be a much easier way to do this.
The only gotcha here is that there may be no match in the database for a specific filter (or all), in which case I want to select the NULL record.
Below I have an excerpt of my embarrassing brute force query -- I first want to try and match on all 5 filters, then on permutations of 4 matching, then 3, then 2, then 1, and finally all Nulls.
incList.FirstOrDefault(x =>
x.Filter1 == filter1Parameter && x.Filter2 == filter2Parameter && x.Filter3 == filter3Parameter && x.Filter4 == filter4Parameter && x.Filter5 == filter5Parameter
|| x.Filter1 == null && x.Filter2 == filter2Parameter && x.Filter3 == filter3Parameter && x.Filter4 == filter4Parameter && x.Filter5 == filter5Parameter
|| x.Filter1 == filter1Parameter && x.Filter2 == null && x.Filter3 == filter3Parameter && x.Filter4 == filter4Parameter && x.Filter5 == filter5Parameter
|| x.Filter1 == filter1Parameter && x.Filter2 == filter2Parameter && x.Filter3 == null && x.Filter4 == filter4Parameter && x.Filter5 == filter5Parameter
|| x.Filter1 == filter1Parameter && x.Filter2 == filter2Parameter && x.Filter3 == filter3Parameter && x.Filter4 == null && x.Filter5 == filter5Parameter
|| x.Filter1 == filter1Parameter && x.Filter2 == filter2Parameter && x.Filter3 == filter3Parameter && x.Filter4 == filter4Parameter && x.Filter5 == null
I originally thought I could have a simple statement that would independently grab the value if present, and grab null if not
incList.FirstOrDefault(x => (x.Filter1 == filter1Parameter || x.Filter1 == null) &&
(x.Filter2 == filter2Parameter || x.Filter2 == null) &&
(x.Filter3 == filter3Parameter || x.Filter3 == null) &&
(x.Filter4 == filter4Parameter || x.Filter4 == null) &&
(x.Filter5 == filter5Parameter || x.Filter5 == null));
But that did not work.
Any pointers would be appreciated.
I'm still trying to understand the full extent of the requirement.
However, have you explored abstracting this Func or Func(s) in a separate class. This separate class or classes would operate like a Strategy. Only in charge of what filters a collection based on a certain predicate.
If that does not seem like a good route, what about looking into writing your own implementation IEqualityComparer. This will allow you determine what makes these objects equal.
You can introduce something like a "fitness function" and then select item with max fit value
var bestMatch = incList.Select(x => new
{
item = x,
fit =
(x.Filter1 == null
? 1
: (x.Filter1 == filter1Parameter ? 2 : 0)) *
(x.Filter2 == null
? 1
: (x.Filter2 == filter2Parameter ? 2 : 0)) // and so on
})
.OrderByDescending(x => x.fit)
.FirstOrDefault(x => x.fit > 0)?.item;
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
So, I'm trying to make something to check if won the lottery automatically.
This game i'm playing has 25 numbers, you can choose 15.
if you hit 15 numbers, you win! (it doesn't need to be in the sequence)
I have a list with all the games called: 'TodosJogos'
and my gamble called: 'Jogado'
Now, I'm doing in this way: (which I think it's a terrible one)
private void VerificaVitoria(Jogo Jogado, string TipoJogo)
{
bool Ganhou;
List<Jogo> LstClassificadas = new List<Jogo>();
LstClassificadas = TodosJogos.Where(x => x.N1 == Jogado.N1 ||
x.N1 == Jogado.N2 ||
x.N1 == Jogado.N3 ||
x.N1 == Jogado.N4 ||
x.N1 == Jogado.N5 ||
x.N1 == Jogado.N6 ||
x.N1 == Jogado.N7 ||
x.N1 == Jogado.N8 ||
x.N1 == Jogado.N9 ||
x.N1 == Jogado.N10 ||
x.N1 == Jogado.N11 ||
x.N1 == Jogado.N12 ||
x.N1 == Jogado.N13 ||
x.N1 == Jogado.N14 ||
x.N1 == Jogado.N15).ToList<Jogo>();
LstClassificadas = LstClassificadas.Where(x => x.N2 == Jogado.N1 ||
x.N2 == Jogado.N2 ||
x.N2 == Jogado.N3 ||
x.N2 == Jogado.N4 ||
x.N2 == Jogado.N5 ||
x.N2 == Jogado.N6 ||
x.N2 == Jogado.N7 ||
x.N2 == Jogado.N8 ||
x.N2 == Jogado.N9 ||
x.N2 == Jogado.N10 ||
x.N2 == Jogado.N11 ||
x.N2 == Jogado.N12 ||
x.N2 == Jogado.N13 ||
x.N2 == Jogado.N14 ||
x.N2 == Jogado.N15).ToList<Jogo>();
LstClassificadas = LstClassificadas.Where(x => x.N3 == Jogado.N1 ||
x.N3 == Jogado.N2 ||
x.N3 == Jogado.N3 ||
x.N3 == Jogado.N4 ||
x.N3 == Jogado.N5 ||
x.N3 == Jogado.N6 ||
x.N3 == Jogado.N7 ||
x.N3 == Jogado.N8 ||
x.N3 == Jogado.N9 ||
x.N3 == Jogado.N10 ||
x.N3 == Jogado.N11 ||
x.N3 == Jogado.N12 ||
x.N3 == Jogado.N13 ||
x.N3 == Jogado.N14 ||
x.N3 == Jogado.N15).ToList<Jogo>();
//.....
Ganhou = LstClassificadas.Count > 0 ? true : false;
if (Ganhou)
{
MessageBox.Show("You won in the game: " + TipoJogo);
}
}
It's the similar to this query:
select * from jogos
where n1 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n2 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n3 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n4 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n5 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n6 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n7 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n8 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n9 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n10 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n11 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n12 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n13 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n14 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
and n15 in(8,18,16,7,5,20,9,6,10,17,22,3,14,21,15)
Is there any better way to do it?
Two ways to solve your problem.
Represent a winning combination as a set of fifteen integers:
HashSet<int>
You have a sequence of winning games:
IEnumerable<HashSet<int>>
and a specific HashSet<int>. You wish to know if the specific set exactly matches any of the winning sets.
Method One
static bool DidIWin(IEnumerable<HashSet<int>> winningNumbers, HashSet<int> myNumbers)
{
return winningNumbers
.Where(winningNumber => myNumbers.SetEquals(winningNumber))
.Any();
}
Or even
static bool DidIWin(IEnumerable<HashSet<int>> winningNumbers, HashSet<int> myNumbers)
{
return winningNumbers
.Any(winningNumber => myNumbers.SetEquals(winningNumber));
}
Method Two
static bool DidIWin(IEnumerable<HashSet<int>> winningNumbers, HashSet<int> myNumbers)
{
return false;
}
Method two is a lot faster. However, it gives the incorrect result on average one time out of every three million winning numbers. This demonstrates that sometimes you can get a big performance win by being willing to accept a tiny amount of inaccuracy.
:-)
Judging from your SQL query, I think this is what you want:
var lotteryNumbers = new int[] { ... };
var results =
from j in jogos
where lotteryNumbers.Contains(j.n1) &&
lotteryNumbers.Contains(j.n2) &&
lotteryNumbers.Contains(j.n3) &&
lotteryNumbers.Contains(j.n4) &&
lotteryNumbers.Contains(j.n5) &&
lotteryNumbers.Contains(j.n6) &&
lotteryNumbers.Contains(j.n7) &&
lotteryNumbers.Contains(j.n8) &&
lotteryNumbers.Contains(j.n9) &&
lotteryNumbers.Contains(j.n10) &&
lotteryNumbers.Contains(j.n11) &&
lotteryNumbers.Contains(j.n12) &&
lotteryNumbers.Contains(j.n13) &&
lotteryNumbers.Contains(j.n14) &&
lotteryNumbers.Contains(j.n15)
select j;
Or in fluent syntax
var results =
jogos.Where(j =>
lotteryNumbers.Contains(j.n1) &&
lotteryNumbers.Contains(j.n2) &&
lotteryNumbers.Contains(j.n3) &&
lotteryNumbers.Contains(j.n4) &&
lotteryNumbers.Contains(j.n5) &&
lotteryNumbers.Contains(j.n6) &&
lotteryNumbers.Contains(j.n7) &&
lotteryNumbers.Contains(j.n8) &&
lotteryNumbers.Contains(j.n9) &&
lotteryNumbers.Contains(j.n10) &&
lotteryNumbers.Contains(j.n11) &&
lotteryNumbers.Contains(j.n12) &&
lotteryNumbers.Contains(j.n13) &&
lotteryNumbers.Contains(j.n14) &&
lotteryNumbers.Contains(j.n15));
Although this assumes you don't have duplicates in either lotteryNumbers or in j.n1 .. j.n15. Otherwise you'd probably get unexpected results.