Sembra che Linq to Entities non supporti il metodo Aggregate
. Devo riscrivere questa parte di un'espressione più grande a .Select(a => a.Permissions).Aggregate((a, b) => a | b)
a qualcosa che Linq alle Entità comprende. È possibile?Collegamento a entità Sostituzione del metodo aggregato
Forse dovrei darti una spiegazione migliore di quello che sto facendo. Devo ottenere una raccolta di Organizzatori dal database in base alle autorizzazioni dell'utente per questi Organizzatori. Le autorizzazioni vengono memorizzate come flag di bit e sono una combinazione dei seguenti elementi:
- DefaultOrganizerPermissions - Ogni organizzatore ha alcune autorizzazioni predefinite
- OwnerPermissions - Se l'utente è il proprietario del organizzatore, ha qualche ulteriore permesso
- UserPermisions - Gli utenti possono essere assegnati manualmente per avere alcune autorizzazioni per Organizer
- RolePermissions - Gli utenti possono essere membri di ruoli e questi ruoli possono essere assegnati per avere autorizzazioni aggiuntive per gli Organizzatori.
Così ho un metodo con la seguente firma
public IQueryable<Organizer> GetOrganizers(Person person, OrganizerPermissions requiredPermissions)
e al suo interno v'è un codice come questo
organizers = organizers.Where(o => ((
// Default permissions
DefaultOrganizerPermissions |
// Owner permissions
(o.OwnerId == person.Id ? OwnerOrganizerPermissions : 0) |
// Personal permissions
(o.AccessIdentifier.Accesses.FirstOrDefault(a => a.Accessor is PersonalAccessor && (a.Accessor as PersonalAccessor).PersonId == person.Id) != null ?
(OrganizerPermissions)o.AccessIdentifier.Accesses.FirstOrDefault(a => a.Accessor is PersonalAccessor && (a.Accessor as PersonalAccessor).PersonId == person.Id).Permissions : 0) |
// Role permissions
(o.AccessIdentifier.Accesses.Any(a => a.Accessor is RoleAccessor && (a.Accessor as RoleAccessor).Role.RoleMembers.Any(rm=>rm.PersonId == person.Id)) ?
(OrganizerPermissions)o.AccessIdentifier.Accesses.Where(a=> a.Accessor is RoleAccessor && (a.Accessor as RoleAccessor).Role.RoleMembers.Any(rm => rm.PersonId == person.Id)).Select(a=>a.Permissions).Aggregate((a, b) => a | b) : 0)
) & requiredPermissions) == requiredPermissions);
semplificata è qualcosa di simile:
organizers = organizers.Where(o => ((
DefaultOrganizerPermissions |
OwnerOrganizerPermissions |
UserPermisions |
RolePermissions
) & requiredPermissions) == requiredPermissions);
Il problema è che l'utente può essere membro di più ruoli, quindi RolePermissions è in realtà più permessi e ho bisogno di appiattirlo con OR bit a bit. Ma come, se Aggregate non è supportato?
Ho provato prima, ma non ha alcun effetto. –
Hai provato questo? .... ToList(). Select (a => a.Permissions) .Aggregate ((a, b) => a | b) ToList() materializza la query (quindi è cattiva) ma dovrebbe funzionare ... avere anche altri modi, come Sum o selezionarne solo uno vero (FirstOrDefault) ma dovresti essere più esplicito. – bubi
@bubi Sì, l'ho fatto. Sto usando acutamente ToList() in un altro metodo della stessa classe e funziona. Ma non funziona in questo. Penso che sia strano, mi aspetterei che funzionasse, o di sollevare qualche (diverso) errore, ma non ci sono cambiamenti. Ho solo bisogno in qualche modo di unire più flag di bit (sono rappresentati come numeri interi), come ad esempio 1010 | 0011 = 1011. Non so se è possibile con Sum. –