Wer*_*ied 5 c# sqlite entity-framework
我不能相信我是第一个遇到这个问题的人,但在网上没有找到任何类似的讨论。
这是简单的完整代码示例:
using SQLite.CodeFirst;
using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Entity entity = new Entity();
Guid id = entity.Id;
using (var context = new MyDbContext())
{
context.Entities.Add(entity);
context.SaveChanges();
// this finds an entry
var item = context.Entities.Find(id);
}
using (var context = new MyDbContext())
{
// here it returns null
var item = context.Entities.Find(id);
}
}
}
public class MyDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new SqliteDropCreateDatabaseWhenModelChanges<MyDbContext>(modelBuilder));
}
public MyDbContext() : base("MyConnection") {}
public DbSet<Entity> Entities { get; set; }
}
public class Entity
{
[Key]
public Guid Id { get; set; } = Guid.Parse("D46D98F3-C262-468A-9C28-83D81080CF18");
public string Name { get; set; } = "Test";
}
}
Run Code Online (Sandbox Code Playgroud)
问题已经在代码中标记出来了。第一个“查找”返回新添加的条目。
但是获取上下文的新实例时,找不到该条目。
即使我第二次运行该应用程序,跳过将条目添加到表中的代码,它也不会找到该项目。问题似乎不是“Find”方法,因为我已经尝试了其他几个 linq 语句,但结果相同。
当我在搜索之前首先从表中获取所有项目时,它适用于“查找”,但不适用于 linq。
这是示例:
using (var context = new MyDbContext())
{
// this returns all items
var allItems = context.Entities.ToArrayAsync().Result;
// this finds the item
var item1 = context.Entities.Find(id);
// this doesn't find the item
var item2 = context.Entities.Where(x => x.Id == id).FirstOrDefault();
}
using (var context = new MyDbContext())
{
// this doesn't find the item
var item1 = context.Entities.Find(id);
// this also doesn't find the item
var item2 = context.Entities.Where(x => x.Id == id).FirstOrDefault();
}
Run Code Online (Sandbox Code Playgroud)
有人有解释吗?将密钥更改为 string 或 int 而不是 GUID,它按预期工作。
好的,我会尝试回答一些言论。
我了解 SQLite 中的 Guid 用法。但因为我想处理外键,所以我认为使用 Guid 而不是数据库生成的键更容易。
查看该表可以看出,Guid 按预期存储为 16 字节 BLOB,并且 DB 中的字节与我使用的 Guid 相对应。
这是该表的表创建语句:
创建表“实体”([Id] uniqueidentifier NOT NULL PRIMARY KEY,[Name] nvarchar)
是的,我在关闭应用程序后阅读了数据库。第二个代码示例是我为此使用的代码示例。我在那里描述了,我第一次使用块它使用 Find 方法找到条目,但不是使用 Linq,并且只有在我之前获取整个表时才找到条目(请参阅我的评论)。之前没有读取所有条目,因为在第二个使用块中没有找到任何条目。
我知道,EF 使用 ADO.NET,但是 EF “生成”SQL 语句来查询数据库,并且 Find 和 linq 之间可能存在某些错误/不同,并且某些内容被缓存,因为当我获取之前整张桌子。生成 SQL 语句是 EF 的一部分,而不是 CodeFirst。所以我认为这个问题与CF无关。即使我使用现有的数据库,在没有 CF 的情况下也会有相同的行为。
没有内存数据库,我在一个应用程序中使用相同的连接字符串运行这两个块。如果我使用数据库浏览器更改“名称”字段,我也会读取这些更改。
我发布了整个代码来测试。可能有人投入一些时间并且可以重现该行为。连接字符串是通用的:
<add name="MyConnection" connectionString="Data Source=c:\test\test.s3db" providerName="System.Data.SQLite.EF6" />
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
787 次 |
| 最近记录: |