注:何が問題なのかを知るためにすべてを読む必要はないかもしれません...必要に応じて、3 つのシナリオに関する部分までスキップしてください。これを実装しようとした方法とエラーが発生した場所に関する背景情報が必要な場合にのみ、最初をお読みください。
まず、特定の のテーブルにClients
格納されている のリストを取得しようとしています。CRM_Clients
callerId
メソッドを使用して、コントローラーからクライアントを取得しますSelectLiveClientsForCaller
。次に、メッセージはstatic Instance
DataProvider クラスのメソッドを介して DAL に渡されます。
public List<Client> SelectLiveClientsForCaller(int callerID)
{
List<Client> results = new List<Client>();
IDataReader reader;
reader = DataProvider.Instance().SelectLiveClientsForCaller(callerID);
if (reader.Read())
{
// If I break here and enumerate the reader, it says that the IEnumerable returned no results
results = CBO.FillCollection<Client>(reader); // Always comes out as a count of 0
}
return results;
}
私DataProvider
のクラスは、利用可能なすべてのメソッドの概要を説明する抽象クラスSqlDataProvider
です。
public abstract class DataProvider
{
// singleton reference to the instantiated object
static DataProvider objProvider = null;
// constructor
static DataProvider()
{
CreateProvider();
}
// dynamically create provider
private static void CreateProvider()
{
objProvider = (DataProvider)Reflection.CreateObject("data", "Owu.Modules.CRM", "");
}
// return the provider
public static DataProvider Instance()
{
return objProvider;
}
public abstract IDataReader SelectLiveClientsForCaller(int callerID);
/* More abstract methods here... */
}
サブクラスSqlDataProvider
では、SelectLiveClientsForCaller
メソッドが実際に処理SqlHelper.ExecuteReader
され、ストアド プロシージャが呼び出されますCRM_Clients_SelectLiveForCaller
。
public class SqlDataProvider : DataProvider
{
private const string ProviderType = "data";
private ProviderConfiguration _providerConfiguration = ProviderConfiguration.GetProviderConfiguration(ProviderType);
private string _myConnectionString;
private string _providerPath;
private string _objectQualifier;
private string _databaseOwner;
private string _moduleQualifier;
public SqlDataProvider()
{
//Read the configuration specific information for this provider
Provider objProvider = (Provider)_providerConfiguration.Providers[_providerConfiguration.DefaultProvider];
//Read the attributes for this provider
//Get Connection string from web.config
_myConnectionString = Config.GetConnectionString();
}
public string MyConnectionString
{
get { return _myConnectionString; }
}
public override IDataReader SelectLiveClientsForCaller(int callerID)
{
return (IDataReader)SqlHelper.ExecuteReader(
myConnectionString,
"CRM_Clients_SelectLiveForCaller",
callerID);
}
/* More methods here... */
}
最後に、ストアド プロシージャCRM_Clients_SelectLiveForCaller
ALTER PROCEDURE [dbo].[CRM_Clients_SelectLiveForCaller]
@CallerID int
AS
BEGIN
SET NOCOUNT ON;
IF @CallerID = -1
BEGIN
SELECT * FROM CRM_Clients WHERE IsDeleted = 'false'
END
ELSE
BEGIN
SELECT * FROM CRM_Clients WHERE ClientID IN
(SELECT ClientID FROM CRM_CallersClients WHERE CallerID = @CallerID)
AND IsDeleted = 'false'
END
END
指定された の削除されていないすべてのクライアントを返しますcallerid
。
これにより、行が戻ってコントローラーから結果が返されます...
私がこれまでに気づいた3つのシナリオがあります
ストアド プロシージャ (SQL Server mgmt studio を介して実行) からレコードが返されない場合、一連のメソッドを呼び出すと
reader.Read()
false が返され、完全にスキップされます。ストアド プロシージャから返されたレコードが 1 つある場合 (SQL Server mgmt studio を介して実行)、一連のメソッドを呼び出すとtrue
reader.Read()
が返されますが、結果を列挙すると、IEnumerable が結果を返さなかったことを示すメッセージが表示されます。ストアド プロシージャから返されるレコードが 2 つある場合 (SQL Server mgmt studio を介して実行)、一連のメソッドを呼び出すとtrue
reader.Read()
が返されますが、結果を列挙すると 2 つではなく 1 つのレコードしか返されません。
各シナリオでこれらの結果が得られる理由を誰か説明できますか?
さらに情報が必要な場合はお問い合わせください。できるだけ早くこれを更新します。
ありがとう、
マット