Simulieren kontextübergreifender Verknüpfungen – LINQ/C#
-
23-08-2019 - |
Frage
Hier ist das Problem:
Ich habe zwei Datenkontexte, für die ich einen Join durchführen möchte.Jetzt weiß ich, dass LINQ keine Verknüpfungen von einem Kontext zu einem anderen zulässt, und ich weiß, dass zwei mögliche Lösungen darin bestehen würden, entweder einen einzelnen Datenkontext zu erstellen oder zwei separate Abfragen zu haben (was ich gerade mache).Was ich jedoch gerne tun würde, ist einen Join zu „simulieren“.
Hier ist, was ich versucht habe.
using (var _baseDataContext = Instance)
{
var query = from a in _baseDataContext.Account.ACCOUNTs
where a.STR_ACCOUNT_NUMBER.ToString() == accountID
join app in _baseDataContext.Account.APPLICATIONs on a.GUID_ACCOUNT_ID equals
app.GUID_ACCOUNT
join l in GetLoans() on app.GUID_APPLICATION equals l.GUID_APPLICATION
select l.GUID_LOAN;
return query.Count() > 0 ? query.First() : Guid.Empty;
}
private static IQueryable<LOAN> GetLoans()
{
using (var _baseDataContext = Instance)
{
return (from l in _baseDataContext.Loan.LOANs
select l).AsQueryable();
}
}
Zur Laufzeit bekomme ich Folgendes
System.InvalidOperationException:Die Abfrage enthält Verweise auf Elemente, die in einem anderen Datenkontext definiert sind
BEARBEITEN:
Arbeitslösung:
using (var _baseDataContext = Instance)
{
var query = from a in _baseDataContext.Account.ACCOUNTs
where a.STR_ACCOUNT_NUMBER.ToString() == accountID
join app in _baseDataContext.Account.APPLICATIONs on a.GUID_ACCOUNT_ID equals
app.GUID_ACCOUNT
join l in GetLoans() on app.GUID_APPLICATION equals l.GUID_APPLICATION
select l.GUID_LOAN;
return (query.Count() > 0) ? query.First() : Guid.Empty;
}
private static IEnumerable<LOAN> GetLoans()
{
using (var _baseDataContext = Instance)
{
return (from l in _baseDataContext.Loan.LOANs
select l).AsQueryable();
}
}
Lösung
Vielleicht ist dies so etwas wie können Sie in der richtigen Richtung zu beginnen. Ich machte eine Mock-Datenbank mit ähnlichen Spalten auf der Grundlage Ihrer Spaltennamen und bekam einige Ergebnisse.
class Program
{
static AccountContextDataContext aContext = new AccountContextDataContext(@"Data Source=;Initial Catalog=;Integrated Security=True");
static LoanContextDataContext lContext = new LoanContextDataContext(@"Data Source=;Initial Catalog=;Integrated Security=True");
static void Main()
{
var query = from a in aContext.ACCOUNTs
join app in aContext.APPLICATIONs on a.GUID_ACCOUNT_ID equals app.GUID_ACCOUNT
where app.GUID_APPLICATION.ToString() == "24551D72-D4C2-428B-84BA-5837A25D8CF6"
select GetLoans(app.GUID_APPLICATION);
IEnumerable<LOAN> loan = query.First();
foreach (LOAN enumerable in loan)
{
Console.WriteLine(enumerable.GUID_LOAN);
}
Console.ReadLine();
}
private static IEnumerable<LOAN> GetLoans(Guid applicationGuid)
{
return (from l in lContext.LOANs where l.GUID_APPLICATION == applicationGuid select l).AsQueryable();
}
}
Hope, das hilft!
Andere Tipps
Dies ist die Lösung, die wir gefunden haben ...
Wir haben unsere Tabellen manuell aus der anderen Datenbank erstellt und wenn sie sich auf demselben Server befindet, haben wir dem Tabellennamen Folgendes vorangestellt:
<DatabaseName>.<SchemaName>.<YourTableName>
Wenn sie sich auf einem Verbindungsserver befinden, müssen Sie ihm auch den Servernamen voranstellen:
<ServerName>.<DatabaseName>.<SchemaName>.<YourTableName>
Auf diese Weise können Sie Verknüpfungen durchführen und dennoch ein nicht ausgeführtes IQueryable zurückgeben ...Das ist es, was wir wollten.Bei den beiden anderen Möglichkeiten handelt es sich um die Verknüpfung von IEnumerables im Arbeitsspeicher, was bedeutet, dass Sie alle Datensätze für jeden Datensatz abrufen, bevor Sie die Verknüpfung (oben) durchführen, und eine IQueryable-Verknüpfung mit einer Methode „Contains“ durchführen, die Einschränkungen aufweist ...
Hoffentlich wird der DataContext in Zukunft intelligent genug aufgebaut sein, um zu wissen, dass Sie Verknüpfungen zwischen zwei verschiedenen Servern durchführen können, wenn die Server miteinander verbunden sind.
Ich bin für einen separaten Datenkontext erstellen, die nur die beiden Tabellen, die Sie anschließen möchten, enthält. Aber ich nehme an, Sie eine temporäre Tabelle halten konnten im zweiten Kontext (Daten aus dem ersten Kontext enthält) und dann die temporäre Tabelle verbinden.