Jetzt, da LINQ to SQL ist ein kleinerer reifer, würde ich gerne über alle Techniken, die Menschen verwenden, um eine n-Tiered-Lösung mit der Technologie zu erstellen, weil es scheint nicht so offensichtlich für mich.Wie wird LINQ To SQL in einer N-Tier-Lösung verwendet?
Antwort
LINQ to SQL hat nicht wirklich eine Geschichte n-Tier, die ich gesehen habe, da die Objekte, die es erstellt in der Klasse mit dem Rest erstellt werden, haben Sie nicht wirklich eine Versammlung, die Sie kann sich gut durch etwas wie Web Services, etc. referenzieren
Die einzige Möglichkeit, die ich wirklich in Betracht ziehen würde, ist das Verwenden des Datenkontextes zum Abrufen von Daten, dann Füllen eines intermediären Datenmodells, Durchreichen und Referenzieren auf beiden Seiten, und verwenden Sie das auf Ihrer Client-Seite - dann geben Sie sie zurück und schieben Sie die Daten zurück in einen neuen Datenkontext oder intelligent aktualisieren Zeilen, nachdem Sie sie erneut holen.
Das ist, wenn ich zu verstehen, was Sie versuchen zu bekommen: \
ich ScottGu die gleiche Frage auf seinem Blog gefragt, als ich es zum ersten Mal gestartet suchen - aber ich habe nicht ein einziges Szenario gesehen oder App in der Wildnis, die auf diese Weise LINQ to SQL verwendet. Websites wie Rob Connery Storefront sind näher am Anbieter.
Hm, Rockford Lhotka traurig, dass LINQ to SQL wunderbare Technologie zum Abrufen von Daten aus der Datenbank ist. Er schlägt vor, dass sie danach gebunden werden müssen, um "Domain-Objekte zu erreichen" (aka. CSLA objetcs).
Ernsthaft gesprochen, LINQ to SQL hatte es Unterstützung für n-Tier-Architektur DataContext.Update Methode.
Möglicherweise möchten Sie in der ADO .Net Entity Framework als Alternative zu LINQ to SQL suchen, obwohl es auch LINQ unterstützt. Ich glaube, LINQ to SQL ist so konzipiert, dass es relativ leicht und einfach ist, während das Entity Framework eher für große Unternehmen geeignet ist und wahrscheinlich besser geeignet ist.
Ernsthaft gesprochen, LINQ to SQL hatte es Unterstützung für n-Tier-Architektur siehe DataContext.Update Methode
Manches, was ich habe gelesen, dass schlägt vor, die Geschäftslogik der Datacontext wickelt - mit anderen Worten: Sie verpacken das Update auf die von Ihnen vorgeschlagene Weise.
Die Art, wie ich Geschäftsobjekte traditionell schreibe, verkapsele ich normalerweise auch die "Load Methoden" in der BO; also könnte ich eine Methode namens LoadEmployeesAndManagers haben, die eine Liste von Mitarbeitern und ihren unmittelbaren Managern zurückgibt (dies ist ein künstliches Beispiel). Vielleicht ist es nur ich, aber in meinem Frontend würde ich lieber e.LoadEmployeesAndManagers() sehen als eine lange LINQ-Anweisung.
Wie auch immer, mit LINQ wäre es wahrscheinlich so etwas wie folgt aussehen (nicht für Syntax Richtigkeit geprüft):
var emps = from e in Employees
join m in Employees
on e.ManagerEmpID equals m.EmpID
select new
{ e,
m.FullName
};
Nun, wenn ich die Dinge richtig verstehe, wenn ich dieses in etwa eine Klassenbibliothek und nennen Sie es aus mein Frontend, der einzige Weg, wie ich das zurückbringen kann, ist ein IEnumerable, also verliere ich meine starke typisierte Güte. Die einzige Möglichkeit, ein stark typisiertes Objekt zurückzugeben, wäre, meine eigene Employees-Klasse (plus ein Zeichenfolgenfeld für den Managernamen) zu erstellen und sie aus den Ergebnissen meiner LINQ to SQL-Anweisung zu füllen und diese dann zurückzugeben. Aber das scheint mir widersinnig zu sein ... was genau hat LINQ to SQL mir gekauft, wenn ich das alles machen muss?
Ich denke, dass ich die Dinge auf die falsche Art betrachten könnte; jede Erleuchtung würde geschätzt werden.
„die einzige Art, wie ich zurückkommen kann, ist als IEnumerable, so verliere ich meine starke typisierten Güte“
, die nicht korrekt ist. In der Tat ist Ihre Abfrage stark typisiert, es ist nur ein anonymer Typ. Ich denke, die Abfrage, die Sie möchten, ist mehr wie:
var emps = from e in Employees
join m in Employees
on e.ManagerEmpID equals m.EmpID
select new Employee
{ e,
m.FullName
};
, die IEnumerable zurückgeben wird.
Hier ist an article Ich schrieb über das Thema.
Linq-zu-SQL ist ein ORM. Es beeinflusst nicht die Art und Weise, wie Sie eine N-Tier-Anwendung entwerfen. Sie verwenden es genauso, wie Sie auch andere ORM verwenden würden.
@liammclennan
Welche IEnumerable zurück. ... Linq-to-sql ist ein ORM. Es beeinflusst nicht die Art und Weise, wie Sie eine N-Tier-Anwendung entwerfen. Sie verwenden es genauso, wie Sie auch andere ORM verwenden würden.
Dann denke ich, ich bin immer noch verwirrt. Ja, Linq-zu-Sql ist ein ORM; aber soweit ich das beurteilen kann, habe ich immer noch meinen front-end-code mit inline-sql-type-anweisungen (linq, nicht sql .... aber immer noch das Gefühl, dass dies weg vom Front-End abstrahiert werden sollte).
Angenommen, die LINQ-Anweisung, die wir als Beispiel in einer Methode verwendet haben, wird umbrochen. Soweit ich sagen kann, ist die einzige Art, wie ich es auf diese Weise zurückkehren kann:
public class EmployeesDAL
{
public IEnumerable LoadEmployeesAndManagers()
{
MyCompanyContext context = new MyCompanyContext();
var emps = from e in context.Employees
join m in context.Employees
on e.ManagerEmpID equals m.EmpID
select new
{ e,
m.FullName
};
return emps;
}
}
Von meinem Front Code Ende ich so etwas tun würde:
EmployeesDAL dal = new EmployeesDAL;
var emps = dal.LoadEmployeesAndManagers();
Dies natürlich gibt eine IEnumerable ; aber ich kann dies nicht wie jede andere ORM verwenden, wie Sie sagen (es sei denn natürlich habe ich falsch verstehen), weil ich das nicht tun kann (auch dies ist ein konstruiertes Beispiel):
txtEmployeeName.Text = emps[0].FullName
Dies ist, was ich mit „Ich meinte, verliere stark typisierte Güte. " Ich glaube, ich stimme Crucible zu; dass LINQ-to-SQL nicht für die Verwendung auf diese Weise entwickelt wurde. Auch wenn ich die Dinge nicht richtig sehe, zeigt mir jemand den Weg :)
OK, ich werde mir eine mögliche Lösung geben.
Inserts/Updates waren nie ein Problem; Sie können die Geschäftslogik in eine Save/Update-Methode einbinden. z.B.
public class EmployeesDAL
{
...
SaveEmployee(Employee employee)
{
//data formatting
employee.FirstName = employee.FirstName.Trim();
employee.LastName = employee.LastName.Trim();
//business rules
if(employee.FirstName.Length > 0 && employee.LastName.Length > 0)
{
MyCompanyContext context = new MyCompanyContext();
//insert
if(employee.empid == 0)
context.Employees.InsertOnSubmit(employee);
else
{
//update goes here
}
context.SubmitChanges();
}
else
throw new BusinessRuleException("Employees must have first and last names");
}
}
Für Abrufen von Daten, oder zumindest das Abrufen von Daten, die aus mehr als eine Tabelle wird kommen, können Sie gespeicherte Prozeduren oder Ansichten verwenden, da die Ergebnisse nicht anonym sein, damit Sie sie von einer externen Methode zurückkehren können. Zum Beispiel unter Verwendung eines gespeicherten Proc: