Xamarin和SQLite:已添加具有相同密钥的项目。关键:3
我想做一些初步的评论:我有很多项目,它使用相同的代码,但以前版本的SQLite(通常为1.2),我没有.NET Core
。Xamarin和SQLite:已添加具有相同密钥的项目。关键:3
我创建了一个新的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; }
}
在第一时间应用程序正确地创建数据库。数据库是空的。
如果我尝试在数据库中添加一个新的记录我收到此错误:
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, Func2 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
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; }
的结果是完全一样的。
在Xamarin Forms
和SQLite-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();
}
}
你能解释一下/节目_how_您添加一个新的记录到数据库?你已经用'AutoIncrement'标记了'Id'字段,所以告诉数据库为'id'列使用特定值可能会导致问题。 – Glubus