2017-10-17 1 views
4

So habe ich eine folgende Abfrage in ef Kern, die ersten oder Standard Aufruf in doppelten Ergebnissen auch hart im Ergebnis auf sieEntity Framework-Kern - Erste Rückkehr doppelte Ergebnisse nach dem .net Kern Migration

DateTime maxDate = SqlDateTime.MaxValue.Value; 
var results = (from r in _dbContext.audit_Results 
       join e in _dbContext.audit_DataEncounters on new { r.IdAudit, r.PatientFirstName, r.PatientLastName, r.PatientDOB } equals new { e.IdAudit, PatientFirstName = e.FirstName, PatientLastName = e.LastName, PatientDOB = e.DateOfBirth } into eJoin 
       let e = eJoin.Where(it => it.StartDate <= r.TransactionDate && r.TransactionDate <= (it.EndDate ?? maxDate)) 
          .OrderBy(it => it.Inpatient).OrderByDescending(it => it.StartDate) 
          .FirstOrDefault() 
       where r.IdAudit == idAudit && r.PatientFirstName == "ERIC" && r.PatientLastName == "BROOKS" 
       select new AuditResultBulkModel() 
       { 
        IdResult = r.IdResult, 
        map_HasPatient = eJoin.Any(), 
        map_IdEncounter = e != null ? e.IdEncounter : (int?)null 
       }).ToList(); 

Den hergestellten Abfrage sieht wie folgt aus:

SELECT * 
FROM [audit_Results] AS [r] 
LEFT JOIN [audit_DataEncounters] AS [e] ON ((([r].[IdAudit] = [e].[IdAudit]) AND (([r].[PatientFirstName] = [e].[FirstName]) OR ([r].[PatientFirstName] IS NULL AND [e].[FirstName] IS NULL))) AND (([r].[PatientLastName] = [e].[LastName]) OR ([r].[PatientLastName] IS NULL AND [e].[LastName] IS NULL))) AND (([r].[PatientDOB] = [e].[DateOfBirth]) OR ([r].[PatientDOB] IS NULL AND [e].[DateOfBirth] IS NULL)) 
WHERE (([r].[IdAudit] = @__idAudit_1) 
ORDER BY [r].[IdAudit], [r].[PatientFirstName], [r].[PatientLastName], [r].[PatientDOB] 

Kann mir jemand sagen, wie die richtigen Ergebnisse zu bekommen aus diesem?

In der Vergangenheit (Entity Framework in. Net Framework) - dies verwendet, um nicht doppelt Ergebnisse mit OUTER APPLY zu produzieren.

Bearbeiten: Meine EF Core-Version ist 2.0.0.

Datenmodell ist wie folgt:

public class audit_Result 
{ 
    [Key] 
    public int IdResult { get; set; } 

    public int IdAudit { get; set; } 

    public bool? map_HasPatient { get; set; } 

    public int? map_IdEncounter { get; set; }   

    public virtual audit_Audit audit_Audit { get; set; } 
} 

public class audit_DataEncounter: IAuditEntity 
{ 
    [Key] 
    public int IdEncounter { get; set; } 

    public int IdAudit { get; set; } 

    [StringLength(50)] 
    public string FirstName { get; set; } 

    [StringLength(50)] 
    public string LastName { get; set; } 

    public DateTime? DateOfBirth { get; set; } 

    public DateTime? StartDate { get; set; } 

    public DateTime? EndDate { get; set; } 

    public bool? Inpatient { get; set; }   

    public virtual audit_Audit Audit { get; set; } 
} 


public class audit_Audit 
{ 
    [Key] 
    public int IdAudit { get; set; } 

    public virtual ICollection<audit_DataEncounter> audit_DataEncounters { get; set; } 

    public virtual ICollection<audit_Result> audit_Result { get; set; } 
} 
+0

Wenn Sie unerwünschte Duplikate erhalten, können Sie sie nicht einfach mit distinct entfernen? Werfen Sie einen Blick auf diesen Beitrag: https://stackoverflow.com/questions/4539668/entity-framework-select-distinct-name – BastianBuhrkall

+0

Bitte buchen Sie das Entitätsmodell in der Abfrage verwendet. Geben Sie auch die EF Core-Version an. –

+0

@IvanStoev Ich habe mein Datenmodell hinzugefügt –

Antwort

5

Leider EF Core-Abfrage Übersetzung ist noch (Stand spätestens zu diesem Zeitpunkt 2,0) weit von den besten. Wenn Sie die EF Core-Protokollierung aktivieren, werden viele Warnungen angezeigt, dass einige Ausdrücke nicht übersetzt werden können und lokal ausgewertet werden (die so genannte Client-Auswertung).

Die einzige Abhilfe, die ich für diese Abfrage vorschlagen könnte, ist die join und let Aussagen zu beseitigen und Unterabfragen verwenden (mit doppelten Filter Joinbedingung) für map_HasPatient und map_IdEncounter Projektionseigenschaften:

var results = (
    from r in _dbContext.audit_Results 
    where r.IdAudit == idAudit && r.PatientFirstName == "ERIC" && r.PatientLastName == "BROOKS" 
    select new AuditResultBulkModel 
    { 
     IdResult = r.IdResult, 
     map_HasPatient = _dbContext.audit_DataEncounters 
     .Any(e => r.IdAudit == e.IdAudit && r.PatientFirstName == e.FirstName && r.PatientLastName == e.LastName && r.PatientDOB == e.DateOfBirth), 
     map_IdEncounter = _dbContext.audit_DataEncounters 
      .Where(e => r.IdAudit == e.IdAudit && r.PatientFirstName == e.FirstName && r.PatientLastName == e.LastName && r.PatientDOB == e.DateOfBirth 
       && e.StartDate <= r.TransactionDate && r.TransactionDate <= (e.EndDate ?? maxDate)) 
      .OrderBy(e => e.Inpatient).ThenByDescending(e => e.StartDate) 
      .Select(e => (int?)e.IdEncounter) 
      .FirstOrDefault() 

    }).ToList(); 

, die auf SQL übersetzt Frage wie folgt:

SELECT [r].[IdResult], (
    SELECT CASE 
     WHEN EXISTS (
      SELECT 1 
      FROM [audit_DataEncounters] AS [e] 
      WHERE ((([r].[IdAudit] = [e].[IdAudit]) AND (([r].[PatientFirstName] = [e].[FirstName]) OR ([r].[PatientFirstName] IS NULL AND [e].[FirstName] IS NULL))) AND (([r].[PatientLastName] = [e].[LastName]) OR ([r].[PatientLastName] IS NULL AND [e].[LastName] IS NULL))) AND ([r].[PatientDOB] = [e].[DateOfBirth])) 
     THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) 
    END 
) AS [map_HasPatient], (
    SELECT TOP(1) [e0].[IdEncounter] 
    FROM [audit_DataEncounters] AS [e0] 
    WHERE ((((([r].[IdAudit] = [e0].[IdAudit]) AND (([r].[PatientFirstName] = [e0].[FirstName]) OR ([r].[PatientFirstName] IS NULL AND [e0].[FirstName] IS NULL))) AND (([r].[PatientLastName] = [e0].[LastName]) OR ([r].[PatientLastName] IS NULL AND [e0].[LastName] IS NULL))) AND ([r].[PatientDOB] = [e0].[DateOfBirth])) AND ([e0].[StartDate] <= [r].[TransactionDate])) AND ([r].[TransactionDate] <= COALESCE([e0].[EndDate], @__maxDate_1)) 
    ORDER BY [e0].[Inpatient], [e0].[StartDate] DESC 
) AS [map_IdEncounter] 
FROM [audit_Results] AS [r] 
WHERE (([r].[IdAudit] = @__idAudit_0) AND ([r].[PatientFirstName] = N'ERIC')) AND ([r].[PatientLastName] = N'BROOKS') 
Verwandte Themen