如何保存具有现有数据和新数据的模型
本文关键字:数据 新数据 模型 保存 何保存 | 更新日期: 2023-09-27 18:24:36
我目前有一个模型,既有现有数据,也有新数据。
举个例子,这是我的模型
public class NameDetails
{
public int Id { get; set; }
public string Name { get; set; }
}
这是它当前拥有的模拟数据
List<NameDetails> Names = new List<NameDetails>{
new NameDetails{Id = 1, Name = "Name 1"},
new NameDetails{Id = 2 , Name = "Name 2"},
};
现在假设我需要将其保存到数据库中。我已经在表中有id = 1,所以这应该是一个更新,因为id = 2应该是一个加法......我该怎么做?
以前,当我使用存储库编写保存时,我进行了添加或编辑像这样添加,
context.NameDetails.Add(NameDetails);
context.SaveChanges();
或像这样编辑,
var recordToUpdate = context.NameDetails.FirstOrDefault(x => x.Id== 1);
recordToUpdate.Name = "New name";
context.SaveChanges();
那么这是否意味着我必须遍历我的列表并找出什么是新的,什么是不是......或者有另一种方法?
您可以使用一些适用于实体框架的约定。
例如,如果在数据库上使用 IDENTITY(1,1)
(因此它会自动为插入的行生成 ID(,则实体属性应使用设置为 Identity
StoreGeneratedPattern
(模型优先方法的情况(,并且具有 0
值的 Id
属性意味着它尚未添加到数据库中。
然后,您可以轻松决定要添加的内容和要更新的内容。下面是一些伪(未经测试的(代码:
foreach (var entity in entities)
{
if (entity.Id == 0)
{
// Adds to the context for a DB insert
context.Entities.Add(entity);
}
else
{
// Updates existing entity (property by property in this example, you could update
// all properties in a single shot if you want)
var dbEntity = context.Entities.Single(z => z.Id == entity.Id);
dbEntity.Prop1 = entity.Prop1;
// etc...
}
}
context.SaveChanges();
仅限 EF5+:
如果你有办法检测一个项目是否是新的(Id == 0 很好,就像 ken2k 的答案一样(,你可以这样做以避免需要映射事物:
foreach(var entity in entities)
{
context.NameDetails.Attach(entity);
context.Entry(entity).State = IsNewEntity(entity)
? EntityState.Added
: EntityState.Modified;
}
这将告诉实体框架为新实体创建插入,为旧实体创建更新。
试试这个:
var nameIds = Names.Select(n => n.Id);
var recordsToUpdate = context.NameDetails.Where(x => nameIds.Contains(x.Id));
实体框架在这些情况下表现不佳。这应该会让你接近你要找的东西:
public class NameDetails
{
public int Id {get;set;}
public string Name {get;set;}
}
List<NameDetails> Names = new List<NameDetails>
{
new NameDetails{Id = 1, Name = "Name 1"},
new NameDetails{Id = 2 , Name = "Name 2"},
};
var toFetch = Names.Select(n => n.Id).ToArray();
var association = context.NameDetails
.Where(n => toFetch.Contains(n.Id))
.ToDictionary(n => n.Id);
foreach(var name in Names)
{
NameDetails existing;
if(association.TryGetValue(name.Id, out existing))
{
// It exists, map the properties in name to existing
}
else
{
// It's new, perform some logic and add it to the context
context.NameDetails.Add(name);
}
}
context.SaveChanges()
或者,您可以尝试劫持执行更新插入的实体框架迁移AddOrUpdate
:
// You need a namespace import of System.Data.Entity.Migrations
context.NameDetails.AddOrUpdate(names.ToArray());
context.SaveChanges();
我还没有尝试过这个,但它应该有效,除非AddOrUpdate
中有一个额外的逻辑让我无法理解。