Dies ist die GET-Methode für den Patienten OData Controller
public class PatientsController : BaseODataController<Patient>
{
public override IQueryable<Patient> Get()
{
return base.Get();
}
...
}
Es kehrt IQueryable <Patient> ...
Das einzige, was wir hinzufügen tun müssen Die Filterung der Zugriffssteuerung erfolgt über die zusätzlichen Prädikate ... Beispiel:
public override IQueryable<Patient> Get()
{
var qry = base.Get();
return qry.Where(itm => itm.Name.FirstName.Contains("R"));
}
Wenn die Steuerung die Infrastruktur IQueryable <T> aufzählt er die gesamte Arbeitseinheit auswertet und erzeugt die endgültige Abfrage.
Wenn ich laufen Spur für die Datenbank und geben ihm eine komplexere OData Abfrage wie
http://localhost/MyService/Patients?$filter=Surgeries/any(d:d/PreOpDataComplete%20eq%20true).
(Mit anderen Worten Praxen finden, wo die PreOpDataComplete Flag wahr ist) Ich werde sehen, die folgende Abfrage ausgeführt wird.
exec sp_executesql N'SELECT
[Project1].[C1] AS [C1],
[Project1].[Id] AS [Id],
[Project1].[Name_FirstName] AS [Name_FirstName],
[Project1].[Name_LastName] AS [Name_LastName],
[Project1].[Gender] AS [Gender],
[Project1].[BirthDate] AS [BirthDate],
[Project1].[MedicalRecordId] AS [MedicalRecordId],
[Project1].[Surgeon_Id] AS [Surgeon_Id]
FROM (SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name_FirstName] AS [Name_FirstName],
[Extent1].[Name_LastName] AS [Name_LastName],
[Extent1].[Gender] AS [Gender],
[Extent1].[BirthDate] AS [BirthDate],
[Extent1].[MedicalRecordId] AS [MedicalRecordId],
[Extent1].[Surgeon_Id] AS [Surgeon_Id],
1 AS [C1]
FROM [dbo].[Patient] AS [Extent1]
WHERE [Extent1].[Name_FirstName] LIKE N''%R%''
) AS [Project1]
WHERE EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Surgery] AS [Extent2]
WHERE ([Project1].[Id] = [Extent2].[Patient_Id]) AND ([Extent2].[PreOpDataComplete] = @p__linq__0)
)',N'@p__linq__0 bit',@p__linq__0=1
Und ich bekomme das erwartete Ergebnis
{
"@odata.context":"http://localhost/MyService/$metadata#Patients",
"value":[{
"Name":{
"FirstName":"Ronn",
"LastName":"Black"
},
"Gender":"M",
"BirthDate":"1917-02-02T00:00:00-08:00",
"MedicalRecordId":"MRN 0001",
"Id":"8bf6dcc4-3f00-4a40-980c-ceb13f8f5360"
}]
}
Wenn ich ein einfaches Sicherheitsmodell übernehmen, wo Chirurgen ihre eigenen Patienten besitzen, und die ich habe eine Liste der Chirurgen ids ich darf zu Zugang in einem Anspruch. Ich würde einen Chirurgen Einheit hat, die etwa wie folgt aussieht:
public partial class Surgeon : IBaseEntity
{
[Key]
public Guid Id { get; set; }
public virtual ICollection<Patient> Patients { get; set; }
. . .
}
Nun, wenn ich die folgende Änderung vornehmen kann ich keine Suche einschränken nur die Patienten, ich darf sehen:
public override IQueryable<Patient> Get()
{
//IQueriable from the OData Selection
var qry = base.Get();
//Enforce Access Security
var accessList = {get list of authorized surgeon id's from claims};
var finalQry = uow.Surgeons
.Where(s => accessList.Contains(s.Id)) //Restrict to Surgeons I'm allowed to see
.SelectMany(surgeon => surgeon.Patients) //All the patients I'm allowed to see (Left)
.Join(qry, //Join to Query (Right)
allowedPatients => allowedPatients.Id, //Key for Left
qryPatients => qryPatients.Id, //Key for Right
(allowedPatients, qryPatients) => //Iterate through Matches
qryPatients); //Return the Matches from Right
return finalQry;
}