Xamarin Sqlite-Net Insert (ссылка на объект не указывает на экземпляр объекта)

У меня очень странная проблема, которую я не могу понять. Я не могу вставить новый элемент в свою базу данных Sqlite. Я продолжаю получать эту ошибку: -

System.NullReferenceException: Object reference not set to an instance of an object.

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

Вот мой код: -

User.cs

public class User
{
    [PrimaryKey, AutoIncrement]
    public int ID { get; set; }
    public string Name { get; set; }
    public string EmailAddress { get; set; }

    public User()
    {
        this.Name = " ";
        this.EmailAddress = " ";
    }
}

UserManager.cs

public class UserManager 
{
    UserRepository repository; 

    public UserManager(SQLiteConnection conn)
    {
        repository = new UserRepository (conn);
    }

    public User GetDriver(int id)
    {
        return repository.GetDriver(id);
    }

    public IList<User> GetDrivers()
    {
        return new List<User>(repository.GetDrivers());
    }

    public int SaveDriver(User item)
    {
        return repository.SaveDriver(item);
    }

    public int DeleteDriver(int id)
    {
        return repository.DeleteDriver(id);
    }
}

UserRepository.cs

public class UserRepository
{
    UserDatabase db = null;

    public UserRepository(SQLiteConnection conn)
    {
        db = new UserDatabase(conn);
    }

    public User GetDriver(int id)
    {
        return db.GetDriverItem(id);
    }

    public IEnumerable<User> GetDrivers()
    {
        return db.GetAllDriverItems();
    }

    public int SaveDriver(User item)
    {
        return db.SaveDriverItem(item);
    }

    public int DeleteDriver(int id)
    {
        return db.DeleteDriverItem(id);
    }
}

UserDatabase.cs

public class UserDatabase
{
    static object locker = new object();
    public SQLiteConnection database;
    public string path;

    public UserDatabase(SQLiteConnection conn)
    {
        database = conn;
        database.CreateTable<User>();
    }

    public IEnumerable<User> GetAllDriverItems () {
        lock (locker) {
            return (from i in database.Table<User>() select i).ToList();
        }
    }

    public User GetDriverItem (int id) 
    {
        lock (locker) {
            return database.Table<User>().FirstOrDefault(x => x.ID == id);
        }
    }

    public int SaveDriverItem (User item) 
    {
        lock (locker) {
            if (item.ID != 0) {
                database.Update(item);
                return item.ID;
            } else {
                return database.Insert(item);
            }
        }
    }

    public int DeleteDriverItem(int id) 
    {
        lock (locker) {
            return database.Delete<User>(id);
        }
    }
}

Application.cs (в Android)

public class UserApp : Application
{
    public static UserApp Current { get; private set; }

    public UserManager UserManager { get; set; }

    SQLiteConnection conn;

    public UserApp(IntPtr handle, global::Android.Runtime.JniHandleOwnership transfer)
        : base(handle, transfer)
    {
        Current = this;
    }

    public override void OnCreate()
    {
        base.OnCreate();

        var sqliteFilename = "UserItemDB.db3";
        string libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        var path = Path.Combine(libraryPath, sqliteFilename);
        conn = new SQLiteConnection(new SQLite.Net.Platform.Generic.SQLitePlatformGeneric(), path);

        UserManager = new UserManager(conn);

        User testUser= new User();
        testUser.Name = "Dave";
        testUser.EmailAddress = "[email protected]";
        UserApp.Current.UserManager.SaveDriver(testUser);
    }

Вот моя трассировка стека: -

System.NullReferenceException: Object reference not set to an instance of an object.
08-09 17:07:32.423 E/mono    (31670):   at     System.Reflection.MonoProperty.GetValue (System.Object obj, System.Object[]     index) [0x00031] in <filename unknown>:0 
08-09 17:07:32.423 E/mono    (31670):   at     SQLite.Net.TableMapping+Column.GetValue (System.Object obj) [0x00000] in     <filename unknown>:0 
08-09 17:07:32.423 E/mono    (31670):   at     SQLite.Net.SQLiteConnection.Insert (System.Object obj, System.String extra,     System.Type objType) [0x00098] in <filename unknown>:0 
08-09 17:07:32.423 E/mono    (31670):   at     SQLite.Net.SQLiteConnection.Insert (System.Object obj) [0x00012] in <filename     unknown>:0 
08-09 17:07:32.423 E/mono    (31670):   at     Project.DataLayer.UserDatabase.SaveDriverItem (Project.BusinessLayer.Models.User     item) [0x00038] in     C:\Users\phill\Desktop\Work\ProjectTEST\Project\Project.Shared\DataLayer\UserDat    abase.cs:42 
08-09 17:07:32.423 E/mono    (31670):   at     Project.DataAccessLayer.UserRepository.SaveDriver     (Project.BusinessLayer.Models.User item) [0x00001] in     C:\Users\phill\Desktop\Work\ProjectTEST\Project\Project.Shared\DataAccessLayer\U    serRepository.cs:30 
08-09 17:07:32.423 E/mono    (31670):   at     Project.BusinessLayer.Managers.UserManager.SaveDriver     (Project.BusinessLayer.Models.User item) [0x00001] in     C:\Users\phill\Desktop\Work\ProjectTEST\Project\Project.Shared\BusinessLayer\Man    agers\UserManager.cs:33 
08-09 17:07:32.423 E/mono    (31670):   at Project.Droid.UserApp+    <getDriverDetails>d__16.MoveNext () [0x000e2] in     C:\Users\phill\Desktop\Work\ProjectTEST\Project\Project.Droid\Application.cs:75 

person Phill Wiggins    schedule 09.08.2016    source источник
comment
Я получаю то же самое, и это сводит меня с ума. Я вернулся к простому использованию команд SQL, но это не идеально.   -  person bertusaurus    schedule 11.08.2016
comment
Привет @ BrettG86 Кажется, я решил свою проблему, твоя похожа?   -  person Phill Wiggins    schedule 11.08.2016


Ответы (1)


Решено - после долгой головной боли я наконец понял проблему.

Итак, NullObject относится к самому файлу базы данных. Структуру БД нельзя изменить, и мое приложение не может создать новую БД из-за некоторых настроек в Xamarin. Не уверен на 100%, какой из них был точным ответом, но вскоре после этого мой проект наконец заработал...

В VS выберите Инструменты > Параметры > Xamarin > Android > Установите флажок "Сохранить данные приложения".

Я думаю, что это главная проблема ^^. Я также проверил / не проверил другие.

Проект > Project.Properties > Параметры Android > Отметьте галочкой Shared Runtime & Fast Deployment и следующую вкладку Linker = None.

Не уверен, что из вышеперечисленного решило мою проблему, но работает отлично.

person Phill Wiggins    schedule 11.08.2016
comment
К сожалению не решил мою проблему. Вы сказали, что это происходит только при вставке в эту таблицу, но для меня это происходит для каждой таблицы. - person bertusaurus; 12.08.2016
comment
Хорошо, это сработало для меня, если я предопределил схему базы данных во внешнем редакторе и сам принудительно задал автоинкремент первичных ключей, определив идентификатор как INTEGER, а не INT. Спасибо. - person bertusaurus; 12.08.2016
comment
В качестве теста запустите этот пример Tasky в своей среде IDE. Код для этого работает хорошо, запустите настройку VS, пробуя разные варианты, чтобы проверить и посмотреть, какой из них начинает работать? - person Phill Wiggins; 13.08.2016
comment
@ BrettG86, что вы имеете в виду, определяя id как INTEGER, а не INT - person Lutaaya Huzaifah Idris; 09.09.2017