Xamarin和SQLite:已添加具有相同密钥的项目。关键:3

问题描述:

我想做一些初步的评论:我有很多项目,它使用相同的代码,但以前版本的SQLite(通常为1.2),我没有.NET CoreXamarin和SQLite:已添加具有相同密钥的项目。关键:3

我创建了一个新的Xamarin项目,并添加了最新版本的sqlite-net-pcl1.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

如果我尝试在数据库中添加一个新的记录我收到此错误:

An item with the same key has already been added. Key: 3

(TKey key, TValue value, Boolean add) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable 1 source, Func 2 keySelector, Func 2 elementSelector, IEqualityComparer 1 comparer) at SQLite.EnumCacheInfo..ctor(Type type) at SQLite.EnumCache.GetInfo(Type type) at SQLite.SQLiteCommand.BindParameter(sqlite3_stmt stmt, Int32 index, Object value, Boolean storeDateTimeAsTicks) at SQLite.PreparedSqlLiteInsertCommand.ExecuteNonQuery(Object[] source)
at SQLite.SQLiteConnection.Insert(Object obj, String extra, Type objType) at SQLite.SQLiteConnection.Insert(Object obj) at MyExpenses.Repository.MyExpensesDatabase.SaveItem[T](T item) at MyExpenses.Repository.MyExpensesRepository.SaveExpense(Expense item)
at MyExpenses.ViewModels.ExpenseItemViewModel.SaveExpenseOnDB() at MyExpenses.ViewModels.ExpenseItemViewModel.d__42.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at 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); 
    } 
} 

我收到了另一种错误

Cannot compile: Parameter

SQLite error

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.CompileExpr(Expression expr, List1 queryArgs) at SQLite.TableQuery1.GenerateCommand(String selectionList) at SQLite.TableQuery1.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) 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, Boolean 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) at System.Runtime.InteropServices.WindowsRuntime.ICommandToWinRTAdapter.Execute(Object parameter)

更新

我在dat中添加了一条新记录有一个共同的功能ABASE:

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; } 

的结果是完全一样的。

+0

你能解释一下/节目_how_您添加一个新的记录到数据库?你已经用'AutoIncrement'标记了'Id'字段,所以告诉数据库为'id'列使用特定值可能会导致问题。 – Glubus

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(); 
    } 
}