Ответ 1
Не с Dapper.Rainbow
Это невозможно в Dapper.Rainbow
в текущей форме, но мой запрос на перенос в github делает это возможным.
Я удивлен, что никто не предлагает использовать Dapper.Contrib
. Я знаю, что я спросил, есть ли функциональность в Rainbow. Но я не ожидал, что никто не заметит этого утверждения (особенно текст выделен жирным шрифтом):
Теперь я искал что-то, что облегчило бы сделать вставки и обновления и нашел Dapper.Rainbow. Я проверил это и был способный использовать его для получения и вставки объектов, как описано выше. мой проблема заключается в том, что когда у продукта есть свойство навигации, я не могу выполнить вставить в это поле.
... и предложите альтернативу, решение, которое уже находится в библиотеке Dapper. Наверное, я должен был уточнить свой вопрос и явно спросил, существует ли какое-то решение во всей библиотеке Dapper, которая находится в github. Поэтому, после более детального изучения в библиотеке, я узнал, что есть поддержка моей проблемы.
Путь к Dapper.Contrib
Все работает хорошо с моим проектом и Rainbow
, пока мне не понадобится больше. У меня есть несколько таблиц, в которых есть много полей. Если я просто буду кормить Rainbow моим объектом, тогда он будет делать обновление со всеми полями, это не все хорошо. Но это не заставляет меня быстро выпрыгнуть из лодки и вернуться в NH. Поэтому, прежде чем я внедрил свой собственный change tracking
, и я не хочу изобретать велосипед, особенно если кто-то уже сделал хорошую работу, я googled вокруг и нашел этот поток SO. Этот поток подтвердил мои знания о том, что Rainbow
не поддерживает отслеживание изменений, но есть еще один зверь, который делает это и он называется Dapper.Contrib
. И поэтому я начал экспериментировать с ним.
И вот мы встретимся снова
Член категории Тип ProductCategory не может использоваться как значение параметра
У меня такая же проблема, как у меня с Rainbow
. Contrib
не поддерживает свойство навигации!? Я начинаю чувствовать, что теряю время с Dapper
, и производительность, которую он предлагает, для меня очень много, будет просто желающим. До...
WriteAttribute, пришел на помощь...
Этот класс живет в файле SqlMapperExtensions.cs
, который включен в проект Dapper.Contrib
. Я не нашел никакой документации по этому классу, и у нее нет комментариев, которые могли бы быть легко найдены и кричать на меня и сказать hey I'm the one you're looking for
. Я наткнулся на это, когда я отложил Радугу, как я описал выше.
Использование этого класса совпадает с тем, что я сделал с IgnorePropertyAttribute
, это атрибут, который вы можете украсить свойством класса. Вы должны украсить этим атрибутом любое свойство, которое вы не хотите включать в sql
, созданный Dapper
. Итак, в моем примере, чтобы я сказал Dapper исключить поле Category
, мне нужно было сделать это:
public class Product {
public int Id {get;set;}
public string Name {get;set;}
[Write(false)] // tell Dapper to exclude this field from the sql
public ProductCategory Category {get;set;}
public int CategoryId {get;set;}
}
Я почти там
Помните, что причина, по которой я перехожу на Contrib
, связана с функциональностью change tracking
. Этот поток SO, та же самая ссылка, которую я дал выше, утверждает, что для отслеживания изменений, которые нужно выполнить, вам нужно иметь интерфейс для своего класса и использовать его с помощью Contrib
, Поэтому для моего класса класса мне нужно:
public interface IProduct {
int Id {get;set;}
string Name {get;set;}
ProductCategory Category {get;set;}
int Category {get;set;}
}
// and implement it on my Product class
public class Product : IProduct {
public int Id {get;set;}
public string Name {get;set;}
[Write(false)]
public ProductCategory Category {get;set;}
int Category {get;set;}
}
Я думал, что это было, почти! Возможно, вы спрашиваете, почему мне нужно определять Category
в моем интерфейсе, если Dapper
вообще не заботится об этом. На самом деле это вызовет только проблему - проблему, которую я тогда разрешу.
В моем конкретном сценарии есть моменты, когда мне нужно работать с полем Category
, сохраняя отслеживание изменений для объекта Product
. Чтобы поддерживать возможности отслеживания, вызов get должен быть подан с типом интерфейса следующим образом:
var product = connection.Get<IProduct>(id);
и с этим вызовом я бы не мог получить доступ к полю Category
, если я не буду определять его в своем интерфейсе. Но если я определяю его в своем интерфейсе, я бы получил знакомую ошибку
Элемент {member} типа {type} не может использоваться как параметр значение.
Действительно снова? Сделайте это, пожалуйста, пожалуйста.
Вердикт
Не нужно беспокоиться, так как это легко решить, украсив член интерфейса так же, как и то, что мы сделали для класса. Таким образом, окончательная конфигурация для работы должна быть:
public interface IProduct {
// I will not discuss here what this attribute does
// as this is documented already in the github source.
// Just take note that this is needed,
// both here and in the implementing class.
[Key]
int Id {get;set;}
string Name {get;set;}
[Write(false)]
ProductCategory Category {get;set;}
int Category {get;set;}
}
// and implement it on my Product class
public class Product : IProduct {
[Key]
public int Id {get;set;}
public string Name {get;set;}
[Write(false)]
public ProductCategory Category {get;set;}
int Category {get;set;}
}
Этот подход можно использовать, если вы предпочитаете работать с Contrib
, у которого есть возможность change tracking
. Если вы хотите работать с Rainbow
и у вас проблемы с навигационным свойством, как и у меня, вы можете играть с моим запросом на перенос. Он работает так же, как и WriteAttribute
, только если он работает с Rainbow
.
Если вы не любите украшать свои классы атрибутами, то оба проекта расширения не для вас. Я знаю, что есть еще один проект расширения, который позволит вам выполнить какую-либо конфигурацию в свободном режиме, но при этом не идет (не входит в основную часть) библиотеки Dapper
то есть в github. Мое предпочтение, которое должно работать только с основной библиотекой, побудило меня исследовать всю библиотеку и посмотреть, нет ли там вещей или если ее можно улучшить для удовлетворения моих потребностей. И это то, что я сделал и объяснил здесь, для Rainbow
и Contrib
.
Я надеюсь, что этот вклад, очень простой класс, который я добавил, советы по настройке, которые я показал, и сценарий, который мне ведёт, помогут кому-то в будущем, кто хочет использовать Dapper, и у него будет такая же настройка, что У меня есть. Кроме того, этот ответ будет обучать разработчиков больше того, что может и не может сделать Dapper. Этот отличный инструмент Dapper
заслуживает лучшей вики, и я надеюсь, что этот ответ/статья здесь в SO помогает даже в малой степени.
** И если то, что я написал здесь, уже где-то написано, что я не нашел в течение двух недель, что я ждал ответа, тогда я буду рад, если кто-нибудь свяжет меня с ним. Прошло уже две недели, и 29 человек, которые заглянули в мой вопрос, не предложили никаких ссылок или решений, поэтому я предположил, что информация, которую я разделяю здесь, является новой для Dapper *:)
ПРИМЕЧАНИЕ. Я изменил название вопроса, чтобы другие могли увидеть это потенциальное решение своей проблемы. Новое название основано на новых знаниях, которые я получил о Dapper.