Как использовать Dapper.Net ORM, как мне сделать вывод хранимой процедуры конкретному типу?

c#-4.0 dapper metadata sql-server-2008-r2 stored-procedures

Вопрос

Используя Entity Framework, я могу создавать конкретные классы из большинства sprocs в базе данных проекта, над которым я работаю. Тем не менее, некоторые из sprocs используют динамический SQL и, таким образом, метаданные не возвращаются для sproc.

Поэтому для этого sproc я вручную создал конкретный класс и теперь хочу сопоставить вывод sproc этому классу и вернуть список этого типа.

Используя следующий метод, я могу получить коллекцию объектов:

                var results = connection.Query<object>("get_buddies", 
                    new {   RecsPerPage = 100,
                            RecCount = 0,
                            PageNumber = 0,
                            OrderBy = "LastestLogin",
                            ProfileID = profileID,
                            ASC = 1}, 
                        commandType: CommandType.StoredProcedure);

Мой конкретный класс содержит

[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();
    .
    .
    .

Без необходимости повторять результаты и добавлять выходные параметры к объекту LoggedInMember, как мне сопоставить их на лету, чтобы я мог вернуть их список через службу WCF?

Если я попробую var results = connection.Query<LoggedInMember>("sq_mobile_get_buddies_v35", ... Я получаю следующую ошибку:

System.Data.DataException: столбец анализа ошибок 0 (RowID = 1 - Int64) ---> System.InvalidCastException: Указанный приведение недействительно. в Deserialize ...

Принятый ответ

Решением этого было создание сложного объекта, полученного из sproc с 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;
            }
        }
    }

В этом случае ProfileDetailsByID_Result является объектом, который я вручную создал с помощью Entity Framework через процесс создания сложного типа (щелкните правой кнопкой мыши на диаграмме модели, выберите «Добавить / сложный тип ...» или используйте дерево «Комплексные типы» в RHS).

СЛОВО ПРЕДОСТЕРЕЖЕНИЯ

Поскольку свойства этого объекта получены из sproc, EF не имеет возможности узнать, является ли свойство нулевым. Для любых типов свойств с нулевым значением вы должны вручную настроить их , выбрав свойство и установив для него свойство Nullable значение true .


Популярные ответы

По предположению ваш столбец SQL является bigint (т.е. Int64 aka long ), но ваш .Net-тип имеет свойство Int16.

Вы можете играть с конверсией и игнорировать хранимую процедуру, делая что-то вроде:

var results = connection.Query<LoggedInMember>("select cast(9 as smallint) [RowID] ...");

Если вы просто выбираете свойства и типы, которые хотите вернуть свой объект. ( smallint является эквивалентом SQL Int16 )



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow