Mat*_*ins 4 c# entity-framework entity-framework-core ef-core-2.0
我正在尝试在EF Core中实现一些在EF 6中非常适合我的东西.
我将List<T>
属性的内容序列化为DB中的Json字符串.<T>
可以是几乎任何东西,因为Json.Net负责序列化我们抛出的任何东西.我的集合公开了一个Json
字符串属性,并负责序列化/反序列化.
这种方法对于结构化嵌套数据来说是方便有效的,其中关系模型会带来不必要的开销和复杂性.
在EF 6中我会做这样的事情:
[ComplexType]
public class SelfSerializingCollection<T> : Collection<T>
{
public void AddRange(IEnumerable<T> collection)
{
foreach (var item in collection)
{
Add(item);
}
}
protected string Json
{
get { return JsonConvert.SerializeObject(this); }
private set
{
Clear();
if (value == null)
{
return;
}
AddRange(JsonConvert.DeserializeObject<T[]>(value));
}
}
}
Run Code Online (Sandbox Code Playgroud)
EF 6不支持映射泛型类型,因此我们为每种类型的List提供了我们可能需要的具体实现:
public class PhoneNumberCollection : SelfSerializingCollection<PhoneNumber> { }
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
public class Contact {
public PhoneNumberCollection PhoneNumbers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
就是这样.现在,我正试图在EF Core 2.0中实现相同的目标.
这是我到目前为止所拥有的.该SelfSerializingCollection<T>
班是不变的.
public class Contact {
// EF Core supports generic types so we don't need a concrete implementation
// for each collection type.
public SelfSerializingCollection<PhoneNumber> PhoneNumbers { get; set; }
}
public class MyDbContext : DbContext
{
// ...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// EF Core does not support the [ComplexType] attribute
// but we now have .OwnsOne() in EF Core 2
modelBuilder.Entity<Contact>().OwnsOne(p => p.PhoneNumbers);
}
}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.EF Core映射PhoneNumbers_Json
数据库中的列.阅读和创建新条目工作得很好.
但是,与EF 6不同,PhoneNumbers
对现有实体上的集合的任何更改都不会持久保存回数据库.我正在使用典型的PUT方法进行更新_context.Entry(contactModelFromRequestBody).State = EntityState.Modified;
- 与之前相同.但由于某种原因,EF Core不会将我的Json
字符串属性保留回Modified
实体的数据库.
有任何想法吗?
EF Core将拥有的类型视为没有自己身份的实体类型,因此指向拥有类型的属性被视为导航属性.并且将父实体状态设置为Modified
不会级联到导航属性.
然而,Update
方法DbContext
或DbSet
做级联,所以而不是
_context.Entry(contactModelFromRequestBody).State = EntityState.Modified;
Run Code Online (Sandbox Code Playgroud)
你应该使用
_context.Update(contactModelFromRequestBody);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
917 次 |
最近记录: |