Reputation: 5895
I got a n:m-Relationship with these three tables:
Now I want to query all Activities
, that have a list of selected Characteristics
attached.
My query:
e.QueryableSource = _dataContext.Activities.Where(ac =>
ac.UserId == _userId &&
ac.ResubmissionDate <= EntityFunctions.TruncateTime(_to) &&
ac.Priority <= (int)_prio &&
ac.CompletedDate == null &&
ac.Characteristics.Contains(CharacFilter));
That sadly doesn't work, as ac.Characteristics.Contains()
expects items of type ActivityCharacteristics
, and not a type of Characteristic
How can I achieve that?
A side node: I don't want an exclusive filtering, say when I specify three characteristics in CharacFilter
, I want to query every activity that may have one of these three characteristics (not necessarily all of them) attached.
Edit:
CharacFilter
is a private IEnumerable<int> CharacFilter { get; set; }
It is being filled from a view where I select those characteristics and hold them in the View-Variable public List<Characteristic> SelectedCharacteristics { get; set; }
My assignment:
var view = new AssignCharacteristicsView();
view.ShowDialog();
if (view.SelectedCharacteristics != null)
{
CharacFilter = view.SelectedCharacteristics.Select(cf => cf.Id);
}
`
Upvotes: 2
Views: 2184
Reputation: 177153
If CharacFilter
is an IEnumerable<Characteristics>
, you could try:
IEnumerable<int> charaFilters = CharacFilter.Select(cf => cf.Id);
e.QueryableSource = _dataContext.Activities.Where(ac =>
ac.UserId == _userId &&
ac.ResubmissionDate <= EntityFunctions.TruncateTime(_to) &&
ac.Priority <= (int)_prio &&
ac.CompletedDate == null &&
ac.Characteristics.Any(acc => characFilters.Contains(acc.CharacteristicId)));
(acc
is of type ActivityCharacteristics
.)
And Activity.Characteristics
should really have the name Activity.ActivityCharacteristics
like you named it in the Characteristics
entity. It's pretty confusing otherwise.
Edit
About your exception
Unable to create a constant value of type 'System.Collections.Generic.IEnumerable´1'
If CharacFilter
is null
you will indeed get this exception because null
is a constant value that EF is unable to create. It won't throw a NullReferenceException
because you are using CharacFilter
in an expression. According to your edited code in the question CharacFilter
could be null
if view.SelectedCharacteristics
is null
.
To solve the problem you have to catch the null
case depending on if view.SelectedCharacteristics == null
means all characteristics or none in your application. If it means none I would suggest to instantiate an empty list:
if (view.SelectedCharacteristics != null)
{
CharacFilter = view.SelectedCharacteristics.Select(cf => cf.Id);
}
else
{
CharacFilter = new List<int>();
}
If it means all characteristics you could try:
// ...
ac.Characteristics.Any(acc => (characFilters != null
? characFilters.Contains(acc.CharacteristicId)
: true)));
Edit 2
Last option throws the same exception (not surprising because to compare CharacFilter
with null
a constant value must be created again). Alternative (just omit the last Where
clause if CharacFilter
is null
):
ObjectQuery<Activity> query = _dataContext.Activities.Where(ac =>
ac.UserId == _userId &&
ac.ResubmissionDate <= EntityFunctions.TruncateTime(_to) &&
ac.Priority <= (int)_prio &&
ac.CompletedDate == null);
if (characFilters != null)
{
query = query.Where(ac => ac.Characteristics
.Any(acc => characFilters.Contains(acc.CharacteristicId)));
}
e.QueryableSource = query;
Upvotes: 4