LINQ
toSQL
がもう少し成熟したので、このテクノロジを使用してn 層ソリューションを作成するために人々が使用しているテクニックを知りたいと思います。
7 に答える
わかりました、私は自分自身に可能な解決策を1つ与えるつもりです。
挿入/更新は決して問題ではありませんでした。ビジネス ロジックを Save/Update メソッドでラップできます。例えば
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");
}
}
データのフェッチ、または少なくとも複数のテーブルからのデータのフェッチには、ストアド プロシージャまたはビューを使用できます。これは、結果が匿名ではないため、外部のメソッドから結果を返すことができるためです。たとえば、ストアド プロシージャを使用すると、次のようになります。
public ISingleResult<GetEmployeesAndManagersResult> LoadEmployeesAndManagers()
{
MyCompanyContext context = new MyCompanyContext();
var emps = context.GetEmployeesAndManagers();
return emps;
}
うーん、Rockford Lhotka残念ながら、LINQ to SQL はデータベースからデータを取得するための優れたテクノロジです。彼は、後でそれらを「リーチ ドメイン オブジェクト」(別名 CSLA オブジェクト) にバインドする必要があることを示唆しています。
真剣に言えば、LINQ to SQL は n 層アーキテクチャをサポートしていました。DataContext.Updateメソッドを参照してください。
LINQ to SQL には、私が見たような n 層のストーリーは実際にはありません。LINQ to SQL が作成するオブジェクトは、残りのオブジェクトと共にクラスで作成されるため、適切に参照できるアセンブリは実際にはありません。 Web サービスなどのようなもの。
私が本当に考える唯一の方法は、データコンテキストを使用してデータを取得し、中間データモデルを埋めて、それを通過させ、両側で参照し、それをクライアント側で使用してから、それらを戻してプッシュすることですデータを新しい Datacontext に戻すか、行を再フェッチした後にインテリジェントに行を更新します。
それは、あなたが取得しようとしていることを私が理解している場合です:\
ScottGu のブログを最初に見始めたとき、私は ScottGu に同じ質問をしましたが、このように LINQ to SQL を使用するシナリオやアプリは実際には見たことがありません。Rob Connery の Storefront のような Web サイトは、プロバイダーに近いです。
ADO .Net Entity Frameworkを LINQ to SQL の代替として検討することをお勧めしますが、 LINQ もサポートしています。LINQ to SQL はかなり軽量でシンプルになるように設計されていると思いますが、Entity Framework はより負荷が高く、おそらく大規模なエンタープライズ アプリケーションにより適しています。
「これを返すことができる唯一の方法はIEnumerableとしてであるため、強い型の良さを失います」
それは正しくありません。実際、クエリは強く型付けされており、単なる匿名型です。私はあなたが望むクエリはもっと似ていると思います:
var emps = from e in Employees
join m in Employees
on e.ManagerEmpID equals m.EmpID
select new Employee
{ e,
m.FullName
};
IEnumerableを返します。
これが私がこのトピックについて書いた記事です。
Linq-to-sqlはORMです。N層アプリケーションの設計方法には影響しません。他のORMを使用するのと同じ方法で使用します。
@リアムクレナン
これは IEnumerable を返します。... Linq-to-sql は ORM です。N 層アプリケーションの設計方法には影響しません。他の ORM と同じように使用します。
それから私はまだ混乱していると思います。はい、Linq-to-Sql は ORM です。しかし、私が知る限り、フロントエンドコードにインラインSQLタイプのステートメントを散らかしています(SQLではなくlinq ....しかし、これはフロントエンドから抽象化する必要があると感じています)。
メソッドの例として使用してきた LINQ ステートメントをラップするとします。私が知る限り、返品できる唯一の方法は次のとおりです。
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;
}
}
私のフロントエンドコードから、次のようなことをします:
EmployeesDAL dal = new EmployeesDAL;
var emps = dal.LoadEmployeesAndManagers();
もちろん、これは IEnumerable を返します。しかし、あなたが言うように、他のORMのようにこれを使用することはできません(もちろん誤解しない限り)。これを行うことはできません(これも不自然な例です):
txtEmployeeName.Text = emps[0].FullName
これが、「強い型付けの良さを失う」という意味です。私は Crucible に同意し始めていると思います。LINQ-to-SQL は、このように使用するようには設計されていません。繰り返しますが、私が物事を正しく見ていない場合は、誰かが私に道を示してくれます:)
真剣に言えば、LINQ to SQL は n 層アーキテクチャをサポートしていました。DataContext.Update メソッドを参照してください。
私が読んだことのいくつかは、ビジネス ロジックが DataContext をラップすることを示唆しています。つまり、提案した方法で更新をラップします。
私が伝統的にビジネスオブジェクトを書く方法は、通常、BO にも「ロードメソッド」をカプセル化します。そのため、従業員とその直属のマネージャーのリストを返す LoadEmployeesAndManagers という名前のメソッドを用意することができます (これは不自然な例です)。私だけかもしれませんが、私のフロント エンドでは、長い LINQ ステートメントよりも e.LoadEmployeesAndManagers() を見たいと思っています。
とにかく、LINQ を使用すると、おそらく次のようになります (構文の正確性はチェックされていません)。
var emps = from e in Employees
join m in Employees
on e.ManagerEmpID equals m.EmpID
select new
{ e,
m.FullName
};
正しく理解できれば、これをたとえばクラス ライブラリに入れてフロント エンドから呼び出すと、これを IEnumerable として返すしかないため、強い型付けの良さが失われます。厳密に型指定されたオブジェクトを返すことができる唯一の方法は、独自の Employees クラス (およびマネージャー名の文字列フィールド) を作成し、LINQ to SQL ステートメントの結果を入力してから返すことです。しかし、これは直感に反するように思えます...すべてを実行する必要がある場合、LINQ to SQLは正確に何を買ってくれましたか?
物事の見方が間違っているのではないかと思います。任意の啓発をいただければ幸いです。