Xamarin和SQLite:已经添加了具有相同键的项。 key:3

时间:2017-07-07 10:40:29

标签: c# sqlite xamarin xamarin.forms

我想做一些初步的评论:我有很多项目,它使用相同的代码,但以前版本的SQLite(通常为1.2),我没有.NET Core

我已经创建了一个新的Xamarin项目,并添加了最新版本的sqlite-net-pcl 1.3.3。我注意到在我的项目中现在有.NET Core。我定义了一个实体

public interface ITableEntityMyExpenses {
    int Id { get; set; }
    bool IsDeleted { get; set; }
    DateTime UpdatedDate { get; set; }
}

然后是BaseTable

public class BaseTableMyExpenses : ITableEntityMyExpenses {
    [PrimaryKey, AutoIncrement]
    [Indexed]
    public int Id { get; set; } = 0;
}

然后是一张桌子

public class Expense : BaseTableMyExpenses {
    public DateTime ExpenseDate { get; set; }
    public int Cost { get; set; }
}

第一次应用程序正确创建数据库。数据库是空的。

Structure

Empty

如果我尝试在数据库中添加新记录,则会收到此错误:

  

已添加具有相同键的项目。关键:3

     

(TKey键,TValue值,布尔加法)at   SQLite.EnumCacheInfo..ctor中的System.Linq.Enumerable.ToDictionary [TSource,TKey,TElement](IEnumerable 1 source, Func 2 keySelector,Func 2 elementSelector, IEqualityComparer 1 comparer)   在SQLite.EnumCache.GetInfo(Type type)at处输入   SQLite.SQLiteCommand.BindParameter(sqlite3_stmt stmt,Int32 index,   对象值,布尔storeDateTimeAsTicks)at   SQLite.PreparedSqlLiteInsertCommand.ExecuteNonQuery(Object [] source)
  在SQLite.SQLiteConnection.Insert(Object obj,String extra,Type   objType)在SQLite.SQLiteConnection.Insert(Object obj)at   MyExpenses.Repository.MyExpensesDatabase.SaveItem [T](T item)at   MyExpenses.Repository.MyExpensesRepository.SaveExpense(费用项目)
  在MyExpenses.ViewModels.ExpenseItemViewModel.SaveExpenseOnDB()at   MyExpenses.ViewModels.ExpenseItemViewModel.d__42.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)在System.Runtime.CompilerServices.TaskAwaiter.GetResult()
  在   MyExpenses.ViewModels.ExpenseItemViewModel< b__41_0> d.MoveNext()

有什么问题?

我还尝试将旧项目更新到SQLite上的新版本。在这种情况下,显然一切正常,但如果我尝试执行此代码

public List<T> GetItems<T>() where T : ITableEntity, new()
{
    lock (locker)
    {
        return (from i in database.Table<T>()
                select i).ToList();
    }
}

public T GetItem<T>(int id) where T : ITableEntity, new()
{
    lock (locker)
    {
        return database.Table<T>().FirstOrDefault(x => x.Id == id);
    }
}

我收到了另一种错误

  

无法编译:参数

SQLite error

  

在SQLite.TableQuery1.CompileExpr(Expression expr,List1 queryArgs)at   SQLite.TableQuery1.CompileExpr(Expression expr,List1 queryArgs)at   SQLite.TableQuery1.CompileExpr(Expression expr,List1 queryArgs)at   SQLite.TableQuery1.CompileExpr(Expression expr,List1 queryArgs)at   SQLite.TableQuery1.GenerateCommand(String selectionList)at   SQLite.TableQuery1.GetEnumerator()at   System.Collections.Generic.List1..ctor(IEnumerable1集合)at   System.Linq.Enumerable.ToList [TSource](IEnumerable1 source)at   SQLite.TableQuery1.FirstOrDefault()at   SQLite.TableQuery1.FirstOrDefault(Expression1 predExpr)at   MyExpenses.Repository.MyExpensesDatabase.GetItem [T](Int32 id)at   MyExpenses.Repository.MyExpensesRepository.GetExpense(Int32 id)at   MyExpenses.ViewModels.ExpenseItemViewModel.LoadData()at   MyExpenses.ViewModels.ExpenseItemViewModel..ctor(Int32 expenseId,   布尔值SaveOnDatabase)at   MyExpenses.Views.ExpenseItem.LoadViewModel(Int32 expenseId)at   MyExpenses.Views.ExpenseItem..ctor(Int32 expenseId)at   MyExpenses.Views.ExpenseList.OnEdit(Object sender,EventArgs e)at   Xamarin.Forms.MenuItem.OnClicked()at   Xamarin.Forms.MenuItem.Xamarin.Forms.IMenuItemController.Activate()at   Xamarin.Forms.Platform.UWP.MenuItemCommand.Execute(Object parameter)   在   System.Runtime.InteropServices.WindowsRuntime.ICommandToWinRTAdapter.Execute(对象   参数)

更新

我在数据库中添加了一条带有常用功能的新记录:

public int SaveItem<T>(T item) where T : ITableEntityMyExpenses
{
    lock (locker)
    {
        if (item.Id != 0)
        {
            database.Update(item);
            return item.Id;
        }
        else
        {
            return database.Insert(item);
        }
    }
}

如果我改变

public int Id { get; set; } = 0;

public int Id { get; set; }

结果完全一样。

1 个答案:

答案 0 :(得分:0)

更新Xamarin FormsSQLite-net-pcl后,肯定会发生变化。大多数功能都运行正常但不是

public T GetItem<T>(int id) where T : ITableEntity, new()
{
    lock (locker)
    {
        return database.Table<T>().FirstOrDefault(x => x.Id == id);
    }
}

你必须改变你的代码:

public T GetItem<T>(int id) where T : ITableEntity, new()
{
    lock (locker)
    {
        return database.Table<T>().Where(x => x.Id == id).FirstOrDefault();
    }
}