【发布时间】:2021-06-27 13:21:08
【问题描述】:
EFCore 的文档(使用 .NET 5)显示,要添加项目,您需要直接使用底层的 DbSet。但是,我目前的设计如下:
我有一个用于获取底层数据集的接口:
public interface IServiceCache
{
IEnumerable<T> Load<T>();
void Save<T>(IEnumerable<T> objList);
}
这支持访问我的底层缓存持久存储。最初我只使用由 JSON 文件支持的文件系统存储来实现这一点。我现在使用DbContext 来实现这一点,这样我就可以在 SQLite 的表中的记录中保存缓存。
现在我已经这样实现了:
internal class DatabaseServiceCache : IServiceCache
{
private readonly IDbContextFactory<DatabaseContext> _contextFactory;
public DatabaseServiceCache(IDbContextFactory<DatabaseContext> contextFactory)
{
_contextFactory = contextFactory;
}
public IEnumerable<T> Load<T>()
{
var context = _contextFactory.CreateDbContext();
return context.Set<T>();
}
public void Save<T>(IEnumerable<T> objList)
{
var context = _contextFactory.CreateDbContext();
// TODO: What to do with `objList`?
// Something like this? `context.Set<T>() = objList` (this won't work obviously)
context.SaveChanges(); // in case elements were modified directly
}
}
还有我的DatabaseContext 班级:
public class DatabaseContext : DbContext
{
public DbSet<IdMapping> CacheIdMapping { get; set; }
}
所以我会像这样使用IServiceCache:
var cache = new DatabaseServiceCache(contextFactory); // assume DI-injected, and that we give it the `contextFactory`
var theList = cache.Load<IdMapping>().ToList();
theList[0].SomeProperty = 100; // modify existing objects
theList.Add(new IdMapping()); // add new objects
cache.Save(theList); // save modified and added items
我的示例中可能存在一些编译器错误;我在运行中修改了我的真实代码以精简它。
所以基本的想法是:
- 我在数据库中查询代表缓存项列表的完整记录集
- 我修改了该列表和/或将新项目添加到同一列表中
- 我保存了列表,其中应该包括修改和添加的项目。
但是,到目前为止,我认为这不会起作用,因为在ToList() 之后执行的唯一更改跟踪是对现有项目的修改。假设该陈述是正确的,我的问题是:
如何将新添加的项目保存回数据库?
请注意,我很高兴得知我的设计需要更改。最初我使用磁盘上的 JSON 文件作为我的主要用例来设计它。所以我可能没有“跳出框框思考”,可能正在尝试将方形钉子装入圆孔中。
我是 EFCore 的新手,所以我也可能缺少一些基本概念。
【问题讨论】:
-
您基本上只需要
context.Set<T>().Add(newT); context.SaveChanges();。 没有别的。代码中的所有这些组件只会掩盖这些简单操作的路径。 -
“模糊路径”意味着什么?
DbSet应该到处传播吗?关注点分离似乎是对我正在做的事情的更积极描述,而不是“模糊”。但就像我在帖子中所说的那样,我很高兴被告知我从设计的角度来处理这个错误。我正在尝试将 EFCore 改造到我现有的架构中,这可能并不理想。
标签: c# entity-framework entity-framework-core