I'm trying to perform a check on the database to see if the combination of two properties exists in the database check (pre-Unique constraint check for better UX). Doing the check with a single property is easy, no matter how many you're trying to check. I'm unable to find how to do it with multiple properties in an enumerable.
public class Foo
{
public int Id { get; set; }
public int Bar { get; set; }
public int Bat { get; set; }
public string Name { get; set; }
//...
}
public class FooDupeCheckModel
{
public int Bar { get; set; }
public int Bat { get; set; }
}
public IEnumerable<FooDupeCheckModel> MatchExists(IEnumerable<FooDupeCheckModel> matches)
{
return _db.Foos
.Where(f => matches.Any(m => m.BarId == f.BarId &&
m.BatId == f.BatId))
.Select(f => new FooDupeCheckModel
{
BarId = f.BarId,
BatId = f.BatId
});
}
This unfortunately gives an exception because the complex property matches
cannot be converted into a SQL script. Only primitive types can be included into a query.
I also tried converting matches
to a multidimensional array before using it within the query, but indexes are not supported within a query. .First()
is not allowed to be used their either.
public IEnumerable<FooDupeCheckModel> MatchExists(IEnumerable<FooDupeCheckModel> matches)
{
var matchArray = matches.Select(m => new [] {m.BarId, m.BatId})
.ToArray();
return _db.Foos
.Where(f => matchArray.Any(m => m[0] == f.BarId &&
m[1] == f.BatId))
.Select(f => new FooDupeCheckModel
{
BarId = f.BarId,
BatId = f.BatId
});
}
This may be one of those situations that is such a niche case, or requires a SQL query that is too complex for Entity Framework that it is not possible. If it is possible, then this would be very helpful if someone else runs into the same issue.
I did get around this by looping through and calling the database for each element in matches
, but if I could do this in one database call, that'd be quicker.