C# 4.0 使用Dapper.NETORM,如何将存储过程输出转换为具体类型?

C# 4.0 使用Dapper.NETORM,如何将存储过程输出转换为具体类型?,c#-4.0,stored-procedures,sql-server-2008-r2,metadata,dapper,C# 4.0,Stored Procedures,Sql Server 2008 R2,Metadata,Dapper,使用实体框架,我可以从我正在处理的项目的数据库中的大多数存储过程中创建具体的类。但是,有些存储过程使用动态SQL,因此不会为存储过程返回元数据 因此,对于该存储过程,我手动创建了一个具体的类,现在希望将存储过程输出映射到此类,并返回此类型的列表 使用以下方法,我可以获得对象集合: var results = connection.Query<object>("get_buddies", new { Recs

使用实体框架,我可以从我正在处理的项目的数据库中的大多数存储过程中创建具体的类。但是,有些存储过程使用动态SQL,因此不会为存储过程返回元数据

因此,对于该存储过程,我手动创建了一个具体的类,现在希望将存储过程输出映射到此类,并返回此类型的列表

使用以下方法,我可以获得对象集合:

                var results = connection.Query<object>("get_buddies", 
                    new {   RecsPerPage = 100,
                            RecCount = 0,
                            PageNumber = 0,
                            OrderBy = "LastestLogin",
                            ProfileID = profileID,
                            ASC = 1}, 
                        commandType: CommandType.StoredProcedure);
var results=connection.Query(“获取好友”,
新{RecsPerPage=100,
RecCount=0,
页码=0,
OrderBy=“LastestLogin”,
ProfileID=ProfileID,
ASC=1},
commandType:commandType.StoredProcess);
我的具体课程包括

[DataContractAttribute(IsReference=true)]
[Serializable()]
public partial class LoggedInMember : ComplexObject
{

   /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.Int16 RowID
    {
        get
        {
            return _RowID;
        }
        set
        {
            OnRowIDChanging(value);
            ReportPropertyChanging("RowID");
            _RowID = StructuralObject.SetValidValue(value);
            ReportPropertyChanged("RowID");
            OnRowIDChanged();
        }
    }
    private global::System.Int16 _RowID;
    partial void OnRowIDChanging(global::System.Int16 value);
    partial void OnRowIDChanged();

    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.String NickName
    {
        get
        {
            return _NickName;
        }
        set
        {
            OnNickNameChanging(value);
            ReportPropertyChanging("NickName");
            _NickName = StructuralObject.SetValidValue(value, false);
            ReportPropertyChanged("NickName");
            OnNickNameChanged();
        }
    }
    private global::System.String _NickName;
    partial void OnNickNameChanging(global::System.String value);
    partial void OnNickNameChanged();
    .
    .
    .
[DataContractAttribute(IsReference=true)]
[可序列化()]
公共部分类LoggedInMember:ComplexObject
{
/// 
///没有可用的元数据文档。
/// 
[EdmScalarPropertyAttribute(EntityKeyProperty=false,IsNullable=false)]
[DataMemberAttribute()]
公共全局::System.Int16 RowID
{
得到
{
返回_RowID;
}
设置
{
onrowiddchanging(值);
报告财产变更(“RowID”);
_RowID=StructuralObject.SetValidValue(值);
ReportPropertyChanged(“RowID”);
OnRowIDChanged();
}
}
私有全局::System.Int16_RowID;
局部无效OnRowidChangeing(全局::System.Int16值);
RowidChanged()上的部分无效;
[EdmScalarPropertyAttribute(EntityKeyProperty=false,IsNullable=false)]
[DataMemberAttribute()]
公共全局::System.String昵称
{
得到
{
return_昵称;
}
设置
{
改变(值);
报告财产变更(“昵称”);
_昵称=StructuralObject.SetValidValue(值,false);
ReportPropertyChanged(“昵称”);
onnickname()已更改;
}
}
私有全局::System.String_昵称;
部分无效(全局::System.String值);
部分无效,已更改();
.
.
.
不必遍历结果并将输出参数添加到LoggedInMember对象,如何动态映射这些参数,以便通过WCF服务返回它们的列表

如果我尝试
var results=connection.Query(“sq\u mobile\u get\u buddies\u v35”…
我会得到以下错误:

System.Data.DataException:分析列0时出错(RowID=1-Int64) --->System.InvalidCastException:指定的强制转换无效。在反序列化时


据猜测,您的SQL列是一个
bigint
(即
Int64
a.k.a.
long
),但您的.Net类型有一个n Int16属性

您可以通过执行以下操作来处理转换并忽略存储过程:

var results = connection.Query<LoggedInMember>("select cast(9 as smallint) [RowID] ...");
var results=connection.Query(“选择cast(9作为smallint)[RowID]…”;

您只需选择要返回对象的属性和类型。(
smallint
是与
Int16
相当的SQL)

解决方案是使用EF创建从存储过程派生的复杂对象:

    public ProfileDetailsByID_Result GetAllProfileDetailsByID(int profileID)
    {
        using (IDbConnection connection = OpenConnection("PrimaryDBConnectionString"))
        {
            try
            {
                var profile = connection.Query<ProfileDetailsByID_Result>("sproc_profile_get_by_id",
                    new { profileid = profileID },
                    commandType: CommandType.StoredProcedure).FirstOrDefault();

                return profile;
            }
            catch (Exception ex)
            {
                ErrorLogging.Instance.Fatal(ex);        // use singleton for logging
                return null;
            }
        }
    }
public ProfileDetailsByID\u结果GetAllProfileDetailsByID(int-profileID)
{
使用(IDbConnection=OpenConnection(“PrimaryDBConnectionString”))
{
尝试
{
var profile=connection.Query(“存储过程\u配置文件\u按\u id获取”,
新的{profileid=profileid},
commandType:commandType.StoredProcess).FirstOrDefault();
回报曲线;
}
捕获(例外情况除外)
{
ErrorLogging.Instance.Fatal(ex);//使用单例进行日志记录
返回null;
}
}
}
在本例中,ProfileDetailsByID_结果是我通过复杂类型创建过程使用Entity Framework手动创建的对象(右键单击模型图,选择Add/Complex Type…,或使用RHS上的复杂类型树)

警告一句

由于此对象的属性是从存储过程派生的,因此EF无法知道属性是否可为Null。对于任何可为Null的属性类型,必须通过选择属性并将其it's nullable属性设置为
true
手动配置这些属性