C
C#2y ago
Tvde1

Query over multiple entities using the same interface [Answered]

I have a EF setup, where ~20 entities implement IArchivable This interface has a public
public Guid Id { get; }
public Guid IsArchived { get; set; }
public Guid Id { get; }
public Guid IsArchived { get; set; }
I wish to perform a query to find the entity with a certain id, and then another query to set the IsArchived property to false. Is this possible with EF? (something like _context.Set<IArchivable>().Where(...) Or should I loop through all types (using reflection) and build an IQueryable for each of them?
7 Replies
ero
ero2y ago
You can't have full lambda bodies in EF right? Pissed me off last time I worked with it too
Tvde1
Tvde12y ago
yeah no full lambda bodies, but you can do a whole lot with expressions
ero
ero2y ago
If you can, you'd do
_context.Set<IArchivable>.FirstAsync(a =>
{
if (a.Id != yourId)
return false;

a.IsArchived = false;
return true;
});
_context.Set<IArchivable>.FirstAsync(a =>
{
if (a.Id != yourId)
return false;

a.IsArchived = false;
return true;
});
Don't know if possible with expressions
Tvde1
Tvde12y ago
let me try if the .Set<Interface> works I think I tried it and it didn't, but I should try again
ero
ero2y ago
Ah, that part wasn't already correct? Don't know the answer on that one
Tvde1
Tvde12y ago
I'm going for something like this now
private static IEnumerable<IQueryable<IArchivableEntity>> GetAllArchivableTypes()
{
var dbProjectTypes = typeof(DataContext).Assembly.GetTypes();
var setMethodInfo = typeof(DataContext).GetMethod(nameof(DataContext.Set), BindingFlags.Public | BindingFlags.Instance);

var archivableEntityTypes = dbProjectTypes.Where(x => x.IsAssignableTo(typeof(IArchivableEntity)) && !x.IsInterface);

return archivableEntityTypes.Select(type => {
var typedMethod = setMethodInfo.MakeGenericMethod(type);
return typedMethod.Invoke(_context, null) as IQueryable<IArchivableEntity>;
});
}
private static IEnumerable<IQueryable<IArchivableEntity>> GetAllArchivableTypes()
{
var dbProjectTypes = typeof(DataContext).Assembly.GetTypes();
var setMethodInfo = typeof(DataContext).GetMethod(nameof(DataContext.Set), BindingFlags.Public | BindingFlags.Instance);

var archivableEntityTypes = dbProjectTypes.Where(x => x.IsAssignableTo(typeof(IArchivableEntity)) && !x.IsInterface);

return archivableEntityTypes.Select(type => {
var typedMethod = setMethodInfo.MakeGenericMethod(type);
return typedMethod.Invoke(_context, null) as IQueryable<IArchivableEntity>;
});
}
let's test if it works
Accord
Accord2y ago
✅ This post has been marked as answered!