注意:您可能不需要阅读整篇文章就知道出了什么问题……如果您愿意,可以跳到关于 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 执行),则在调用方法序列时
reader.Read()
返回true但枚举结果会给出一条消息,说IEnumerable 返回没有结果如果从存储过程返回2条记录(通过sql server mgmt studio执行),调用方法序列时
reader.Read()
返回true但枚举结果仅返回1条记录而不是2条
谁能解释为什么我在每种情况下都得到这些结果?
如果您需要更多信息,请询问,我会尽快更新。
谢谢,
马特