2

データ アクセスに Dapper を使用しようとしています (ASP.NET MVC3 FWIW で)。次のような T-SQL ビュー (SQL Server 内) があります。

SELECT s.*, c.CompanyId AS BreakPoint c.Name AS CompanyName
FROM tblStaff AS s
INNER JOIN tblCompanies AS c ON c.CompanyId = s.CompanyId

とてもシンプルです。基本的に、それぞれが 1 つの会社を持つスタッフのリストです。

私が抱えている問題は、このクエリの出力を POCO にマップしようとしていることですが、ビューの各フィールドは一意でなければならないため (つまり、tblStaff に既に存在する Name ではなく CompanyName)、POCO へのマッピング動作していません。

コードは次のとおりです。

var sql = @"select * from qryStaff";
var people = _db.Query<Person, Company, Person>(sql, (person, company) => {person.Company = company; return person;}, splitOn: "BreakPoint");

このパズルを解く方法について何かアドバイスはありますか? 私は現在、どのように進歩するかについて困惑しているので、ビューのやり方を変えることにオープンです。

4

1 に答える 1

0

ビューから返されたすべてのフィールドを明示的にリストする必要があり(アスタリスクはありません!)、フィールド名が一意でない場合は、エイリアスを使用して重複排除を行います。例として:

SELECT 
    s.CompanyName as CompanyName1, 
    s.BreakPoint as BreakPoint1,
    ...
    c.CompanyId AS BreakPoint,
    c.Name AS CompanyName
FROM tblStaff AS s
INNER JOIN tblCompanies AS c ON c.CompanyId = s.CompanyId

リストされているフィールドと使用する可能性のあるエイリアスは、もちろん、完全にコードに依存します。通常、POCOのプロパティ名と一致するようにクエリのエイリアスを調整します。

また、一般的な経験則として、このような問題が発生するため、SQLクエリでワイルドカードを使用しないことをお勧めします。これは、SQLクエリのベストプラクティスに関する適切な記事です。

抜粋:

コード内のSELECTステートメントで列の明示的な名前を使用すると、いくつかの利点があります。まず、SQL Serverは、アプリケーションが必要とするデータのみを返し、アプリケーションが使用しない一連の追加データは返しません。必要なデータのみを返すことにより、SQLServerが必要な情報のすべての列を収集するために実行する必要のある作業量を最適化できます。また、アスタリスク(*)の命名法を使用しないことで、SELECTステートメントに関連付けられたデータをアプリケーションに送信するために必要なネットワークトラフィックの量(バイト数)も最小限に抑えられます。

さらに、列に明示的に名前を付けることで、SELECTステートメントで参照するテーブルに発生する可能性のあるデータベーススキーマの変更に関連する潜在的な障害からアプリケーションを保護します。アスタリスク(*)の命名法を使用し、誰かがテーブルに新しい列を追加した場合、アプリケーションは、アプリケーションコードを変更しなくても、この追加のデータ列のデータの受信を開始します。アプリケーションが特定の数の列のみが返されることを期待していた場合、誰かが参照されたテーブルの1つに列を追加するとすぐに失敗します。したがって、SELECTステートメントで列に明示的に名前を付けることにより、アプリケーションは常に同じ数の列を返します。

于 2012-04-18T16:05:06.723 に答える