如何从 EF Core 中的 JSON 更新实体
How to update entities from JSON in EF Core
我正在将数据从 EF 核心序列化到 JSON 文件。我的型号和配置:
public class Customer
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Order
{
[Key]
public Guid Id { get; set; }
public Guid CustomerGuid { get; set; }
[JsonIgnore]
public virtual Customer Customer { get; set; }
public string OrderType { get; set; }
}
public class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.HasMany(p => p.Orders).WithOne(d => d.Customer).HasForeignKey(d => d.CustomerGuid);
}
}
public class OrderConfiguration : IEntityTypeConfiguration<Order>
{
public virtual void Configure(EntityTypeBuilder<Order> builder)
{
builder.HasOne(p => p.Customer).WithMany(p => p.Orders).HasForeignKey(d => d.CustomerGuid);
}
}
我将一位客户序列化到 JSON 文件:
{
"Id": "18a55fea-89cd-438a-bae0-4954193807bf",
"Name": "Customer1",
"Orders": [
{
"Id": "f253837f-5428-405a-880e-2af2b597094c",
"CustomerGuid": "18a55fea-89cd-438a-bae0-4954193807bf",
"OrderType": "OrderType1"
},
{
"Id": "0a288fe3-0a00-4372-810f-3d682f82f1dc",
"CustomerGuid": "18a55fea-89cd-438a-bae0-4954193807bf",
"OrderType": "OrderType2"
},
{
"Id": "0df4a724-598c-44d7-a6eb-4d597501520f",
"CustomerGuid": "18a55fea-89cd-438a-bae0-4954193807bf",
"OrderType": "OrderType0"
}
]
}
现在,我将 "Name": "Customer1"
从 JSON 文件更改为 "Name": "Customer2"
,我也想从 EF 核心更新数据库。我希望 "Id": "18a55fea-89cd-438a-bae0-4954193807bf"
的 Name
的数据库客户是 Customer2
。我可以使用此 ID 删除客户并创建新客户,但我想更新它。在这种情况下,我可以这样做:
var customerFromJson = JsonConvert.DeserializeObject<Customer>(json);
var customerFromDB = context.GetEntities<Customer>().Single(c => c.Id == customerFromJson.Id);
customerFromDB.Name = customerFromJson.Name;
context.SaveChanges();
但是除了 Name
属性 可能还有其他属性,我不想手动执行此操作。有什么好的解决方案,硬代码或其他方法可以解决这个问题吗?
我建议为此使用 AutoMapper。因此,您获得实体并将 json 对象中的所有字段映射到其中:
mapper.Map(customerFromJson, customerFromDB);
context.SaveChanges();
没有简单的方法可以做到这一点。正如 Gleb 所提到的,您可以使用 automapper(得到我的支持)但要小心。
您 json 中的不存在的值将变为空值,空值将被复制到数据库中。所以不要忘记添加条件。
另一种方法是使用反射并根据您的 json 检查目标中存在哪些属性。这几乎就是 automapper 所做的。
即便如此,这两种解决方案都使用了性能很重的反射。您针对少数列的解决方案最有意义。
我正在将数据从 EF 核心序列化到 JSON 文件。我的型号和配置:
public class Customer
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Order
{
[Key]
public Guid Id { get; set; }
public Guid CustomerGuid { get; set; }
[JsonIgnore]
public virtual Customer Customer { get; set; }
public string OrderType { get; set; }
}
public class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.HasMany(p => p.Orders).WithOne(d => d.Customer).HasForeignKey(d => d.CustomerGuid);
}
}
public class OrderConfiguration : IEntityTypeConfiguration<Order>
{
public virtual void Configure(EntityTypeBuilder<Order> builder)
{
builder.HasOne(p => p.Customer).WithMany(p => p.Orders).HasForeignKey(d => d.CustomerGuid);
}
}
我将一位客户序列化到 JSON 文件:
{
"Id": "18a55fea-89cd-438a-bae0-4954193807bf",
"Name": "Customer1",
"Orders": [
{
"Id": "f253837f-5428-405a-880e-2af2b597094c",
"CustomerGuid": "18a55fea-89cd-438a-bae0-4954193807bf",
"OrderType": "OrderType1"
},
{
"Id": "0a288fe3-0a00-4372-810f-3d682f82f1dc",
"CustomerGuid": "18a55fea-89cd-438a-bae0-4954193807bf",
"OrderType": "OrderType2"
},
{
"Id": "0df4a724-598c-44d7-a6eb-4d597501520f",
"CustomerGuid": "18a55fea-89cd-438a-bae0-4954193807bf",
"OrderType": "OrderType0"
}
]
}
现在,我将 "Name": "Customer1"
从 JSON 文件更改为 "Name": "Customer2"
,我也想从 EF 核心更新数据库。我希望 "Id": "18a55fea-89cd-438a-bae0-4954193807bf"
的 Name
的数据库客户是 Customer2
。我可以使用此 ID 删除客户并创建新客户,但我想更新它。在这种情况下,我可以这样做:
var customerFromJson = JsonConvert.DeserializeObject<Customer>(json);
var customerFromDB = context.GetEntities<Customer>().Single(c => c.Id == customerFromJson.Id);
customerFromDB.Name = customerFromJson.Name;
context.SaveChanges();
但是除了 Name
属性 可能还有其他属性,我不想手动执行此操作。有什么好的解决方案,硬代码或其他方法可以解决这个问题吗?
我建议为此使用 AutoMapper。因此,您获得实体并将 json 对象中的所有字段映射到其中:
mapper.Map(customerFromJson, customerFromDB);
context.SaveChanges();
没有简单的方法可以做到这一点。正如 Gleb 所提到的,您可以使用 automapper(得到我的支持)但要小心。
您 json 中的不存在的值将变为空值,空值将被复制到数据库中。所以不要忘记添加条件。
另一种方法是使用反射并根据您的 json 检查目标中存在哪些属性。这几乎就是 automapper 所做的。
即便如此,这两种解决方案都使用了性能很重的反射。您针对少数列的解决方案最有意义。