Dapper с Mapping по коду: Multi-Mapping с повторяющимися именами столбцов - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь выполнить простой запрос, и в результате почти все данные null.

У меня есть эта структура таблицы

Стол Registros

ID            |  Autonumeric
TareaM_Id     |  Numeric
Fecha         |  Date/Time

и таблица Macro_tareas

ID            |  Autonumeric
Nombre        |  Short Text

Я сопоставил классы в C # следующим образом:

[Table("Registros")]
public class Registro
{
    [Column("ID")]
    public virtual int ID { get; set; }

    [Column("Fecha")]
    public virtual DateTime Fecha { get; set; }

    [Column("TareaM_Id")]
    public virtual int TareaM_Id { get; set; }

    public virtual MacroTarea MacroT { get; set; }
}

[Table("Macro_tarea")]
public class MacroTarea
{
    [Column("ID")]
    public virtual int ID { get; set; }

    [Column("Nombre")]
    public virtual string Nombre{ get; set; }

    public virtual ICollection<Registro> Registros { get; set; }

}

Это запрос, который я пытаюсь использовать

string sql = @"SELECT reg.ID, mac.ID 
    FROM Registros as reg INNER JOIN Macro_tarea as mac on reg.TareaM_Id = mac.ID
    WHERE Fecha = @Fecha";

using (IDbConnection db = new OleDbConnection(ConnectionString))
{
    var result = db.Query<Registro,MacroTarea, Registro>(sql, 
    (reg,mac) =>
    {
        reg.MacroTarea = mac;
        return reg;
    }
    ,new { @Fecha = new DateTime(2019, 1, 4).Date }
    , splitOn: "mac.ID")
    .AsList();                                            
}

Я пытаюсь получить только идентификаторы, но оба идентификатора становятся нулевыми, почему это происходит?

Дело в том, что если я добавлю Registros.Fecha и Macro_tarea.Nombre к запросу, он получит значение правильно. Но идентификатор все равно обнуляется.

Видимо, проблема происходит только с идентификаторами. Я подозреваю, что эта проблема связана с дублированием имен столбцов.

Я работаю с Microsoft Access только в касте, который имеет значение.

Мой вопрос не похож на возможный дубликат , потому что у меня определены классы так, как они должны отображаться.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Проблема заключалась в названии свойств.

Я решил это с помощью Custom Column Mapping, чтобы сделать это, у меня есть два возможных решения:

Без расширений

Сначала мы определяем словарь с именем столбца в качестве ключа и именем свойства в качестве значения

IDictionary<string, string> columnMaps = new Dictionary<string, string>()
            {
                { "Macro_tarea.ID", "ID" },
                { "Registros.ID", "ID" }
            };

Затем мы определяем делегата для получения объекта PropertyInfo свойства, которому мы намереваемся присвоить псевдоним предыдущего словаря

var mapper = new Func<Type, string, PropertyInfo>((type, columnName) =>
            {
                if (columnMaps.ContainsKey(columnName))
                    return type.GetProperty(columnMaps[columnName]);
                else
                    return type.GetProperty(columnName);
            });

Теперь мы определяем объект, который реализует интерфейс ITypeMap, используя CustomPropertyTypeMap реализацию

ITypeMap MacroTareaMapper = new CustomPropertyTypeMap(typeof(Macro_tarea),
                (type, columnName) => mapper(type, columnName));

ITypeMap RegistrosMapper = new CustomPropertyTypeMap(typeof(Registros),
                (type, columnName) => mapper(type, columnName));

Тогда мы их регистрируем

SqlMapper.SetTypeMap(typeof(Macro_tarea), MacroTareaMapper);
SqlMapper.SetTypeMap(typeof(Registros), RegistrosMapper);

Более простое решение с Dapper.FluentMap

Это реализовано следующим образом:

Мы создаем класс, который наследуется от EntityMap<T> и, используя метод Map, определяем, какой столбец соответствует каждому свойству. Например,

internal class Macro_tareaMap : EntityMap<Macro_tarea>
{
       internal Macro_tareaMap()
       {
            //Mi propiedad ID esta asociada a la columna Macro_tarea.ID
            Map(x => x.ID).ToColumn("Macro_tarea.ID");
       }
}

Тогда просто зарегистрируйте его

FluentMapper.Initialize((config) => 
{
    config.AddMap(new Macro_tareaMap());
});

Надеюсь, это поможет другим людям!

Источник: https://medium.com/dapper-net/custom-columns-mapping-1cd45dfd51d6

0 голосов
/ 07 января 2019

Как мы обсуждали в комментариях, это проблема из-за дублирования имен столбцов в двух таблицах. В этом можно найти похожую проблему и решение. Но оно не включает "отображение по коду" , как вы сказали. Так что это не точно дубликат.

Я предлагаю вам изменить имена полей ID в ваших таблицах, чтобы избежать их столкновения. Конечно, вам также следует соответствующим образом изменить имя ваших свойств POCO и сопоставлений.

Если вы не можете изменить имена столбцов в таблице, измените имя свойства POCO и используйте псевдоним столбца в запросе SQL, чтобы сопоставить эти новые имена свойств.

Надеюсь, это поможет вам.

...