✅ I want to get duplicate items in my List (EF Core)
I am trying to get a list of Cards from my database, and I am able to successfully get a List of Guids, where there are duplicate values, but when I try to use an efficient .Where() using .Contains(), it only returns 1 of the Card that shows up multiple times in the list. Here is my code:
cardList
is a List<Card>
, and originally my code did a foreach loop over the List of Guids, but that caused a lot of DB queries, so I found that doing .Contains helps, and it works fine, except it doesn't add duplicates, when I want it to.
Hope this makes sense! Thanks!21 Replies
For example, if
deckList
contains 17 values, where 6 are the same value, cardList
will return 12 items instead of 17 (only 1 instance of the duplicate value)this means your card ids are identical
and also this code is weird
look at the queries it generates
you are using i.Id instead of i.CardId, is that relevant?
Well what I have is a table of Cards that are identified by their ID, so there will be instances where a deck list will have multiple of the same ID
Yes, but I need to account for that, is there perhaps a better way to loop over a list of IDs like that without using foreach? Rider complains to me about excessive DB calls when I used foreach before 😅
yes, with a join in sql
which you can get in a variety of ways in ef core
the easiest way is probably navigation properties
but you should really learn some sql basics
Ah okay I see, I did try a join before but it returned 0 cards but I bet my logic was messed up. I’ll look into that, thank you!
Doing a foreach is fine, as long as you do ToListAsync first; ToListAsync pulls it out of the database, one query. (Or more specifically, as long as it's not an IEnumerable anymore then the query is done)
What's inefficient here is that it's doing two queries
Just pull out the cards directly if you want a list of them, and you generally shouldn't be using IDs, EF can handle the navigations, so it'd just be
var cardList = myDeck.Cards
Thanks for the tip! And could you explain the idea of not using IDs? What I have is a table called
DeckContents
and it’s basically a M-M relation of DeckIDs and CardIDs, so what I do is when I pull the deckList, I get all CardIDs that match the DeckID I’m grabbing. Is there a better way?Just put a List<Card> in your DeckContents class
and a List<Deck> in your Card class
and wire up the EF configuration to tell it they're many to many
😳 that’s so cool. I’ll look into that, thanks!
Hm okay so what I have so far is a List<Card> inside of my DeckContents class, with the DeckId as the Key. Is that right? Because a Deck has the details of the Deck (Name, description, Owner) and DeckContents is purely for keeping track of what Cards are in the Deck
Is that the only list I need? Or do I need to put something in the Card class to relate them?
Inside of DeckContent class:
public virtual List<Card> DeckList { get; set; }
Inside of ApplicationDbContext class builder:
builder.Entity<DeckContent>().HasMany(i => i.DeckList).WithMany();
read the documentation on navigation properties
virtual
🤢
And do you want a many-to-many relationship? If so, then neither the deck would hold the ID of the card, nor the card would hold the ID of the deckI think I'm actually going for a one-to-many, and I did remove the virtual haha
I got it working how I want, where it returns a List of Cards, but it's still omitting duplicate Cards ://
This is from my seeder, and it's a list of 20 cards, but when I retrieve the list of Cards from the database, it only returns 14
Ah, I think I know why
Relationships in a many-to-many are exclusive, meaning only one relationship between given elements can exist at any time
If you want one-to-many, meaning one card can belong only to one, single deck, that problem goes away
Ahhh okay so I do want many to many, hm
Because any number of decks can have any number of cards
Or is that one-to-many? 😵💫
If it helps, I’m working with Magic the Gathering cards, so imagine many decks with many cards, even duplicates of the same card
It's many-to-many, yes
And there is a way to solve it, just need to configure the join entity and introduce another identifier
Something like this
I’ll try that! Thanks!
The only part of this that doesn't work is this section:
It's saying that it can't resolve symbol
PrimaryKey
, like it isn't a valid part of j
So I tried it out without that section and I got this error after trying to save data to the database:
*without just the j.PrimaryKey
part, I did add the j.HasKey
partIDK about how to solve that problem, but it also might be worth thinking about having CardInDeck contain a Quantity, and then not dealing with duplicates at all. This deck has 4 of this ID, done
Depending on how you use it and why you need to know duplicates, and if that makes it easier.
Somehow, I figured it out and got it to work, I just had to give the
DeckContent
class its own ID to use as its PK, it now returns a List of Cards, including duplicates!This is how I'm able to get the list now
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.