Xamarin Linq вставляет/обновляет запись таблицы Sqlite со сгенерированным столбцом

Для таблицы, определенной

public class Tbl 
{

    [PrimaryKey]
    public int Id { get; set; }
    public string Col2 { get; set; }
    public string Gen { get; set; }

}

Где Gen - это сохраненный в Sqlite всегда сгенерированный столбец

on _conn.Insert(instanceOfTbl)

я получаю 'cannot UPDATE generated column'.

Достаточно справедливо, но помимо прямого выполнения эквивалентного оператора sql, который игнорирует Gen, есть ли способ пометить Gen как сгенерированный (или другой метод), чтобы разрешить вставку/обновление? Я не думаю, что атрибут столбца [Игнорировать] подходит, поскольку Gen должен быть доступен для чтения. Удаление метода доступа Set предотвращает поведение, но приводит к тому, что свойство всегда имеет значение null при чтении.

Я использую VS, Xamarin, Nuget sqlite-net-pcl 1.7.335 для Android, если это применимо.


person Antony Fox    schedule 15.03.2021    source источник
comment
попробуйте сделать его доступным только для чтения (уберите set)   -  person Jason    schedule 15.03.2021
comment
Спасибо Джейсон. Я забыл упомянуть, что пробовал это. Я изменил вопрос, добавив: «Удаление средства доступа Set предотвращает поведение, но приводит к тому, что свойство всегда имеет значение null при чтении».   -  person Antony Fox    schedule 16.03.2021
comment
вам, возможно, придется прибегнуть к двум классам для этой таблицы: один для чтения (с Gen) и один для обновления (без)   -  person Jason    schedule 16.03.2021
comment
Еще раз спасибо, Джейсон. Решение, которое я не хотел слышать, но вполне может быть правильным :)   -  person Antony Fox    schedule 18.03.2021


Ответы (1)


Я решил принять этот подход на данный момент. Спасибо Джейсону за то, что он указал мне на это.

Разделить Tbl на базовый класс Tbl и производный класс TblEx. Переместите созданное свойство столбца в TblEx. Hardwire TblEx для сопоставления с таблицей Sqlite Tbl. Предоставьте метод TblEx для получения только свойств из базового класса Tbl.

public class Tbl 
{
    [PrimaryKey]
    public int Id { get; set; }
    public string Col2 { get; set; }
}

[SQLite.Table("Tbl")]
public class TblEx : Tbl
{
    public string Gen { get; set; }
    public Tbl GetTbl() {Tbl t = new Tbl(); t.Id = Id; t.Col2 = Col2; return t;}
}

Обновить запись с идентификатором первичного ключа

    TblEx tEx = _conn.Table<TblEx>().First(t => t.Id == id);

    // Generated field is available as class is TblEx
    tEx.Col2 = tEx.Gen + "something";  

    //Update now works as only base class Tbl without reference to generated column is passed
    _conn.Update(tEx.GetTbl());

Альтернативный способ получения базового класса использует сериализацию/десериализацию JSON, преимущество которой заключается в том, что не нужно явно назначать значения свойств, но это может привести к затратам на производительность или ограничениям совместимости типов (я не уверен, что последнее верно, поскольку я не ' я много знаю о JSON).

using System.Text.Json;

[SQLite.Table("Tbl")]
public class TblEx : Tbl
{
    public string Gen { get; set; }
    public Tbl GetTbl()
    {return JsonSerializer.Deserialize<Tbl>(JsonSerializer.Serialize(this));}
}
person Antony Fox    schedule 19.03.2021