![](/img/trans.png)
[英]How to get extended properties of sql table in Entity framework (EF6)?
[英]Entity Framework (EF6) insert or update if exists for properties
假设模型如下:
class Foo {
virtual Bar Bar {get; set ;}
}
class Bar {
int Id { get; set; }
string Property {get; set;}
}
class MyContext {
virtual DbSet<Foo> Foos {get; set;}
void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Bar>()
.HasKey(c => c.Property);
}
}
和一些类似的代码:
void DoStuff() {
var foos = GetFoosFromExternalSource();
using(var ctx = new MyContext() {
foreach(var foo in foos) {
ctx.Foos.Add(foo);
}
ctx.SaveChanges();
}
}
IEnumerable<Foo> GetFoosFromExternalSource() {
yield return new Foo {
Bar = new Bar { Id = 1, Property = "Hello" }
};
yield return new Foo {
Bar = new Bar { Id = 2, Property = "World" }
};
yield return new Foo {
Bar = new Bar { Id = 1, Property = "Hello" }
}
}
这将引发异常:
违反主键约束'PK_dbo.Bar'。 无法在对象“ dbo.Bar”中插入重复键。 重复的键值为(Hello)。
我如何向EF明确指出,如果Bar对象具有相同的Key(或Id,或两者),则它被视为同一实例?
我知道如果我能做些类似的事情
IEnumerable<Foo> GetFoosFromExternalSource() {
var bar1 = new Bar { Id = 1, Property = "Hello" };
var bar2 = new Bar { Id = 2, Property = "World" };
yield return new Foo {
Bar = bar1
};
yield return new Foo {
Bar = bar2
};
yield return new Foo {
Bar = bar1
}
}
会很好的。 但是,由于这是来自外部源的数据,因此这是不可能直接实现的。 我的真实场景具有多个级别和许多属性。 所以我想在模型中解决这个问题。
而不是添加实体,您应该使用“ upsert”库(或创建自己的库)。 例如, FlexLabs.Upsert就是这样的Entity Framework Core库。
在您的情况下,代码将如下所示(基于docu):
async Task DoStuff()
{
var foos = GetFoosFromExternalSource();
using(var ctx = new MyContext()
{
await ctx.Foos
.UpsertRange(foos)
.On(f => f.Property)
.RunAsync();
ctx.SaveChanges(); // not sure if savechanges call is necessary based on docu...
}
}
注意:我以前没有使用过FlexLabs.Upsert , 前段时间有朋友向我推荐了它,还没有时间对其进行进一步的试验。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.