SQLを記述しないADO.net(特にWHERE)
-
03-07-2019 - |
質問
SQL VIEWSを使用して単純なデータベース計算(リレーションのカウントなど)を抽象化するだけで十分であり、プロシージャ(==プロシージャコード)は必要ないという考えがあります
単純なSQL ビュー + where 句<!> gt; <!> gt;時々パラメータを持つストアドプロシージャ
この点を述べながら、SQLを記述せず、where句を記述せずにテーブル/ビューデータを取得する方法を想像しました。
しかし、驚いたことに、ADO.NET 2.0以降ではこれを実現する方法がないようです。
試したことを教えてください:
-
SqlDataAdapter + SqlCommandBuilderでは、<!> quot; SELECT ... FROM <!> quot;を記述する必要があります。および文字列内の WHERE CLAUSE (さらに、「where」を入力すると、Update / Insert / DeleteCommandの使用頻度が低くなります)
-
型指定されたデータセットでは、_Table全体を取得してからフィルターを適用することのみが可能です。フィルタは文字列であり、補助をエスケープしません...(一重引用符を2倍にする必要があります!)
-
SQL to Entitiesは有望に見えましたが、MSSQLに限定され、肥大化したSQLクエリを生成し、DAOのまったく新しいスタックを生成します(既存のドメインモデルクラスに加えて)、このすべてにreqiuire .net 3.5+など(つまり、これらはすべて私にとって不利な点です)
他のORMには、SQL to Entitiesと同様の問題があります。
探しているのは、データベーステーブル/ ビュー にアクセスするための強力な型指定の方法です。
- 別のDAOセット(K.I.S.S)は付属していません
- <!> quot; SELECTs <!> quot;を記述せずにテーブルをクエリできます。文字列(厳密な型指定)
- 適切にエスケープされたパラメーターを使用して(事前にデータ全体を取得せずに)テーブルをフィルター処理( WHERE )できます
- 後で更新/挿入/削除を発行できます
私は.Netを初めて使用しますが、愚かではありません:これは存在しますか?
ありがとう。
他のヒント
あなたがやりたいことは、何らかのORM、またはデータベーススキーマ、型/列情報について何らかの形で知っているコンパイラを備えた特別なDSLを使用せずに達成できるとは本当に信じていませんなど
C#は汎用言語であり、そのコンパイラはデータベースタイプをまったく認識していないことを考慮してください。そのため、通常、アドホックSQLクエリ(文字列)、NHibernateまたは同様のマッピングファイル(より多くの文字列)および/またはDAO。
WHERE句を書きたくない場合、1つの方法はFilterオブジェクトを使用して、必要な条件を追加することです。例:
var sc = new Filter();
sc.Add("Contacttitle", "Sales Agent");
sc.Add("city", "london", Logical.Or);
var customers = D2Bk.Fetch(sc, new Customers());
しかし、DAO(上記の顧客はそうです)を使用したくないので、SQLステートメントを記述し、where句を指定する必要があります:
DataSet ds = D2Bk.Fetch("SELECT * FROM Customers WHERE Contacttitle=@PAR1 OR City=@PAR2", "Sales Agent", "london");
LINQ および ADO.Net Data Services で、これらが要件の一部を満たしていませんか?
Native ADO.Netはデータベースプロバイダーであるため、基礎となるデータソースへの直接的なSQLインターフェイスを提供します。さまざまな程度の提案をシミュレートする、さまざまなCRUBベースのソリューションがあります。
主にまだサポートが必要なDelphiコードベースのため、データベースをデータベースチームに任せ、データベースへのメインインターフェースとしてWebサービスを使用するという内部的な傾向があります。
実際には、 ADO.Net Entity Framework ADO.Net Data Servicesで特に使用されます。 LINQ to Entitiesプロバイダーもあります。
ストアドプロシージャを使用して、このようなことを1回行いました。基本的に、WHERE句で一致するフィールドの順列を指定したかったのですが、わずかに異なるparamリストとwhere句を持つ100個のsprocを書きたくありませんでした。
だから、私はこのようなことをしました:
CREATE PROCEDURE [GetSimpleCustomers]
(
@ID varchar(50) = null,
@Name varchar(50) = null,
@IsActive bit = null,
@Address1 varchar(50) = null,
@Address2 varchar(50) = null,
@City varchar(50) = null,
@State varchar(50) = null,
@Zip varchar(50) = null
)
AS
SELECT ID, Name, IsActive, Address1, Address2, City, State, Zip
FROM SimpleCustomerExample
WHERE (ID = @ID OR @ID is NULL)
AND (Name = @Name OR @Name is NULL)
AND (IsActive = @IsActive or @IsActive is NULL)
AND (Address1= @Address1 or @Address1 is NULL)
AND (Address2= @Address2 or @Address2 is NULL)
AND (City= @City or @City is NULL)
AND (State= @State or @State is NULL)
AND (Zip= @Zip or @Zip is NULL)
これにより、コード内でsprocを呼び出して、フィルター処理に関心のあるパラメーターのみを渡すことができます。nullのままにした場合、残りは考慮されません。
つまり、次のようなことができます
public List<SimpleCustomer> GetAllCustomersFromOhio()
{
List<SimpleCustomer> list = new List<SimpleCustomer>();
using (SqlCommand cmd = new SqlCommand(blah blah))
{
cmd.Parameters.AddWithValue("State", "Ohio");//or "OH" depending on your convention
using(IDataReader oDR = cmd.ExecuteReader())
{
//hydrate your list of SimpleCustomers from the record set.
}
}
return list;
}
編集: コメントへの返信:
を変更することで、GetSimpleCustomersをDeleteSimpleCustomersに簡単に変更できます。SELECT <columns> FROM SimpleCustomers
to
DELETE FROM SimpleCustomers
同じロジックを保持します。同じことがアップデートにも当てはまります。 また、質問に答えます。このレベルのカスタムフィルタリングを実際に必要とするテーブルはいくつありますか?シンタックスは非常に似ているので、1日ですべてを片付けることができます(または、簡単なスクリプトを作成して作成する場合はそれよりも少なくなります)。
厳密に型指定されたDataSetを使用している場合、クエリに@というプレフィックスを付けた識別子を追加することにより、Visual Studio Editorでパラメーター化されたクエリを作成できます。 Visual StudioでDataSet XSDファイルを作成し、Productsという新しいテーブルを作成してから、新しいクエリを追加します。
例:
select * from Products where Category = @category;
これにより、入力済みのデータセットのメソッドが自動生成されるか、追加のパラメーターを受け取るデータテーブルが取得されます。また、文字列を適切にエスケープします(コマンドオブジェクトのパラメーターを使用します)。これを使用して、非常に簡単にいくつかの非常に簡単なプロトタイプのWebアプリを作成しました。
最近、SQL where句を生成するクエリ「フレームワーク」を作成しました。
プライマリコンポーネントは、リフレクションを使用してプロパティを文字列セクションに変換するToWhereClause()関数を持つBaseQueryArgsクラスです。これは、値をエスケープして適切にフォーマットする作業を処理する必要があります。
BaseQueryArgsを継承するクラスは、単にパブリックプロパティを宣言するだけでよく、厳密に型指定されたクエリオブジェクトになります。オプションのプロパティの場合、値をnull可能(ref型またはNullable <!> lt; <!> gt;)にすると、SQLジェネレーターはnull値を除外します。
カスタム属性を使用して、各プロパティの追加機能を定義できます。
- プロパティ名とは異なるカスタム列名
- カスタム値の処理(BETWEENテスト式として使用される日付値など)
これは、次のような厳密に型指定されたクエリオブジェクトでクエリを作成するために使用できます。
MyCustomQueryArgs args = new MyCustomQueryArgs
{
ProductFamilyID = 17,
Region = Regions.Northwest,
Active = true
};
List<Product> product = QueryProcessor.GetProductsWhere(args);
GetProductsWhere()は、明らかに、生成されたSQLでビューにアクセスするデータメソッドを呼び出します。
更新/削除の解決策はありませんが、テーブル名を決定するためにスイッチまたは属性を使用してオブジェクトインスタンスをSQLステートメントに変換するメソッドを記述することは難しくないようです。
これは非常に<!> quot;独自のロール<!> quot;ですが、ニーズに合わせて自由にカスタマイズでき、大量のORM / DAOラッピングは含まれていません。
Mindscapes Lightspeed 製品をご覧ください
さまざまなデータベースエンジン全体で効率的なSQLコードを生成し、MemcachedおよびLuceneのサポートを含む、厳密に型指定されたLINQクエリ可能モデルを構築します
複数のプロジェクトでXPOを使用しましたが、新しいバージョンではクエリのサポートが向上しています。
http://www.devexpress.com/Products/NET/ORM/
すべての実装と同様に、実装には欠点がないわけではありません。
プロジェクトには Data Abstract を使用しています。