I have a collection (local array, filled from elsewhere) with a set of Section
and Lines
. These are NOT primary keys.
Say something like this:
class SectionLine {
int Section { get; }
int Line { get; }
}
class MyEntity {
int EntityId { get; set; }
int Section { get; set; }
int Line { get; set; }
string OtherProperty { get, set; }
// Many other options...
}
// ...
SectionLine[] allSectionLines = new [] { new SectionLine { Section = 5, Line = 2 }, new SectionLine { Section = 5, Line = 3 }, // etc.
So I want to filter my collection on the DbContext for those that match -both- section and line from any in the array allSectionLines
.
Note that Section
and Line
on the entity MyEntity
are not primary keys, but they do have a multi-column index which would be great if it would be usable.
I can see a couple options but I don't like any... namely:
- Multiple queries, one for each element in
allSectionLines
. This array comes from a different source (it's not code-static) and could have many elements, so I don't like this. Edit: This also applies to making a composite predicate with manyOR
clauses... if the number in the array collection is big enough I'm sure this would perform rather poorly - Creating a single property from the multi-property, something like:
var sectionLines = allSectionsLines.Select(x => x.Section + "-" + x.Line);
var myQuery = _dbContext.MyEntities.Where(x => sectionLines.Contains(x.Section + "-" + x.Line));
This works, but it does full table scans and doesn't take the index into account, so I'd prefer to avoid it
- Create a stored procedure on the database and do some multi-column joins, first inserting the array on a temp table (or passing this table as a parameter): this definitely works but this database is managed by someone else and I'm not doing any kind of migrations. I could definitely ask for the SP to be there... but if it's solvable by code, I'd prefer to do it without "touching" the database schema
And there's another hack I'm doing now (projecting the entities to a simple DTO-like type with just ID, Section and Line, then filter in memory and get the IDs, then query again for those IDs). This works JUST because of the data that is there and the available memory and speed of the actual server, but I do not like it.
Is there another way I haven't found of doing such a query, preferably directly on Entity Framework, which doesn't waste memory, extra "seemingly unneeded" queries, and may use the indexes on the database instead of doing full scans?
This is EF Core 3.1
Addendum: my current line of thought is adding a calculated field (with an index) for the "Section-Line" string and perform the query there... again, I'm not the owner of the database so I'd prefer not "having to ask for it"... but if that's the only way I can actually do it. It's not that it's not solvable... I'm just evaluating alternatives and seeing if I'm missing an obvious one