如何从实体框架中存在数据模型的json中反序列化对象?
Posted
技术标签:
【中文标题】如何从实体框架中存在数据模型的json中反序列化对象?【英文标题】:How to DeserializeObject from json where data model exist in Entity Framework? 【发布时间】:2019-08-12 16:36:47 【问题描述】:我有一个传入的 json 对象,它代表从数据库结构中提取的数据。
我想将它映射到实体框架模型,该模型具有来自属性或来自数据库上下文中的模型构建器的定义。
在运行实体框架时,此数据正确映射,因此我知道模型是正确的。
所以使用相同的结构,而不是通过 EF 调用数据库,我从一个 API 中提取,该 API 具有与 entity.Property 列名称相同的传入数据结构。
如何将传入的 json 结构映射到模型对象?
属性
[Table("model_example")]
public class ModelExample
[Column("property_to_map")] // <-- db column name
public int PropertyToMap get; set;
或ModelBuilder
:
modelBuilder.Entity<ModelExample>(entity =>
entity.ToTable("model_example");
entity.Property(e => e.PropertyToMap).HasColumnName("property_to_map");
传入的 JSON 示例:
"property_to_map":1
因此,如果从数据库中提取此数据,它将自动映射到“ModelExample.PropertyToMap”和 ModelExample 代码模型。
如何映射它?有没有办法使用实体框架流程?
更新
我知道如何使用 Newtonsoft 从 json 映射到对象。我正在尝试映射到实体而不必使用映射器。实体框架已经有了这些值,我希望只是使用实体框架配合。
【问题讨论】:
也许可以添加一个您希望发生这种情况的方法调用示例,以及您尝试过的示例或您希望在何处进行此转换的示例。如果这是从客户端接收 JSON 数据并希望自动被解释为实体的情况,我强烈建议不要这样做,来自客户端的数据很容易被篡改,不应该被信任为可以附加到上下文并提交到数据库。 【参考方案1】:我过去曾使用来自 Newtonsoft 的 JsonConvert.DeserializeObject 来执行此操作。希望这会有所帮助。
class Example
public int property_to_map get; set;
class ApiCalls
public void MakeApiCall()
var response = ApiCall();
var MappedObject = JsonConvert.Deserialize<Example>(response);
//Do whatever you need now with the mapped object.
【讨论】:
这也不是我指的,我知道如何从json转换。我希望得到已经使用的 Example.PropertyToMap 值。也许我不想使用映射器。 哦,好吧,相信你还是可以用newtonsoft的。它有一个属性,您也可以分配蛇案例名称,因此它分配给 PropertyToMap 而不是 property_to_map:***.com/questions/15915503/…【参考方案2】:好吧,我决定改为更改 Json 字符串,而不是将 json 强制转换为模型。
我通过创建自定义 JsonConverter 并在其中重命名 JProperty 来做到这一点。
构建一个通用的 JsonConverter 基类
public abstract class JsonCreationConverter<T> : JsonConverter
protected abstract T CreateArray<TJsonType>(Type objectType, TJsonType jObject);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
throw new NotImplementedException("Unnecessary because CanWrite is " +
"false. The type will skip the converter.");
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
if (reader.TokenType == JsonToken.Null)
return null;
JArray jArray;
var target = default(T);
try
jArray = JArray.Load(reader);
target = CreateArray<JArray>(objectType, jArray);
catch (Exception ex)
return null;
return target;
public override bool CanConvert(Type objectType)
return typeof(T).IsAssignableFrom(objectType);
public override bool CanWrite
get return false;
构建自定义 JSON 转换器。
public class JsonEntityConverter<TObject> : JsonCreationConverter<TObject>
protected override TObject CreateArray<TJsonType>(Type objectType, TJsonType tArray)
var deserializedObj = default(TObject);
var jArray = (JArray)Convert.ChangeType(tArray, typeof(JArray));
var newjArray = new JArray();
foreach (var item in jArray.Children())
var itemProperties = item.Children<JProperty>();
var jObj = new JObject();
foreach (var itemProperty in itemProperties)
var name = itemProperty.Name.ToModelName(); // <-- Code Below #3
var newJproperty = new JProperty(name, itemProperty.Value);
jObj.Add(newJproperty);
newjArray.Add(jObj);
var sObject = Newtonsoft.Json.JsonConvert.SerializeObject(newjArray);
deserializedObj = Newtonsoft.Json.JsonConvert.DeserializeObject<TObject>(sObject);
return deserializedObj;
将 JSON 属性名称 property_to_map
转换为实体属性名称 PropertyToEmpty
public static partial class StringsExtensions
// Changes example_id to exampleId for mapping
public static string ToModelName(this string text)
// First we make a space
text = text.Replace("_", " ");
// Capitalize every word
text = text.ToUpperEveryWord(); // <-- Code Below #4
// remove the extra space
text = text.Replace(" ", "");
return text;
每个单词都大写
public static string ToUpperEveryWord(this string s)
// Check for empty string.
if (string.IsNullOrEmpty(s))
return string.Empty;
var words = s.Split(' ');
var t = "";
foreach (var word in words)
t += char.ToUpper(word[0]) + word.Substring(1) + ' ';
return t.Trim();
我怎么称呼它
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<TType>(item.ToString(), new JsonEntityConverter<TType>());
【讨论】:
以上是关于如何从实体框架中存在数据模型的json中反序列化对象?的主要内容,如果未能解决你的问题,请参考以下文章
JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 `byte[]` 的实例
[C#]如何使用Newton.Json从流中反序列化json数据