Нельзя использовать пользовательский тип в качестве параметра в Dapper-запросе для вставки в базу данных SQLite. - PullRequest
1 голос
/ 16 марта 2019

У меня есть класс Player, у которого есть Id, Имя пользователя и Ранг:

class Player
{
    public int Id { get; set; }
    public string Username { get; set; }
    public Rank Rank { get; set; }
}

Я хочу вставить новый проигрыватель в базу данных SQLite, для этого я использую Dapper.

При нажатии кнопки формы:

Player newPlayer = new Player();
Rank newRank = new Rank();
newPlayer.Username = txtUsername.Text;
newPlayer.Rank = newRank;

if (newPlayer.Username != null && newPlayer.Username != String.Empty)
{               
    SQLiteDataAccess.SavePlayer(newPlayer);
    Close();
}

Мой C Метод RUD в «SQLiteDataAccess»

public static void SavePlayer(Player player)
{
    using (IDbConnection connection = new SQLiteConnection(LoadConnectionString()))
    {
        connection.Execute("insert into Players (Username, Rank) values (@Username, @Rank)",
                           player);
    }
}


Мой класс "Rank" состоит из строкового имени и нескольких целых чисел. У меня есть конструктор, который устанавливает все значения по умолчанию "-" и 0.

При использовании этого пользовательского типа «Ранг» в качестве параметра возникает проблема:

System.NotSupportedException: 'Ранг члена типа Prototype1.Rank нельзя использовать в качестве значения параметра '

Есть ли способ обойти это или другой способ без использования Dapper?

Ответы [ 2 ]

3 голосов
/ 16 марта 2019

Прежде всего, используйте string.IsNullOrEmpty() вместо if (newPlayer.Username != null && newPlayer.Username != String.Empty).

Сам Даппер не делает такой вставки. Вы должны сначала добавить свой класс ранга и привязать идентификатор к типу значения RankID в своем классе игрока. Например:

public class Player
{
    public int Id { get; set; }
    public string Username { get; set; }
    public int RankId { get; set; }
    public Rank Rank { get; set; }
}

public class Rank
{
    public int Id { get; set; }
    public string Something { get; set; }
}

public class Repo
{
    public void Save(Player player)
    {
        // .. open connection
        player.RankId = connection.ExecuteScalar<int>("insert into Rank (Something) values (@Something)", player.Rank);
        player.Id = connection.ExecuteScalar<int>("insert into Player (Username, RankId) values (@Username, @RankId", player);
    }
}
2 голосов
/ 16 марта 2019

Вы можете использовать только примитивные типы в качестве параметров при вставке в таблицу с помощью Dapper.

У вас есть, по крайней мере, следующие варианты:

a) Если отношение Player-Rank равно One-to-One, вы можете реорганизовать модель вашего класса, чтобы класс Player содержал все поля из вашегоРанг-класс, а затем удалите свой Ранг-класс.Также вы можете изменить свое предложение вставки для вставки только в один ряд игроков с примитивными типами.

b) Если отношение Player-Rank равно One [Player]-to-Many [Ranks], вы можете выполнить рефакторинг своего решения, сначала вставив Rank (в собственную таблицу, содержащую PlayerId в качестве внешнего ключа), а затемОбъект игрока с его полями.

...