我很懒地将我的表数据加载到JSON结果中,然后将它们发送到前端应用程序。但是当我得到这些数据时,我注意到有不必要的元素,在响应中存在空元素。正因为如此,我的PUT
或update操作不适用于这些内部JSON属性。
{
"image":null,
"paragraph":null,
"question":{
"grid":null,
"elements":[
],
"offeredAnswers":[
],
"lazyLoader":{
},
"id":"1",
"text":"How can we serve you better?",
"type":"textarea",
"questionRequired":false,
"pageFlowModifier":false,
"gridId":null,
"min":null,
"max":null
},
"lazyLoader":{
}
}
如果我改变text
的值,它不会得到更新,但如果我改变paragraph
,那么它将在数据库中被改变。
这里有一个新的属性lazyLoader
,我也需要去掉它。和elements
,offeredAnswers
实际上不需要,因为它们是空的。我通过在引用的类中添加virtual
关键字来实现延迟加载。
public partial class Questions
{
public Questions()
{
Elements = new HashSet<Elements>();
OfferedAnswers = new HashSet<OfferedAnswers>();
}
public string Id { get; set; }
public string Text { get; set; }
public string Type { get; set; }
public bool QuestionRequired { get; set; }
public bool PageFlowModifier { get; set; }
public int? GridId { get; set; }
public long? Min { get; set; }
public long? Max { get; set; }
public virtual Grids Grid { get; set; }
public virtual ICollection<Elements> Elements { get; set; }
public virtual ICollection<OfferedAnswers> OfferedAnswers { get; set; }
}
我在Startup.cs
文件中有这一行来停止引用循环处理,因为没有这一行,POST
操作就不起作用,因为我发布的JSON
对象非常复杂,里面有引用循环。
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
我已经启用了延迟加载代理。
services.AddDbContext<RDS_Context>
(options => options.UseLazyLoadingProxies().UseSqlServer(connection));
4条答案
按热度按时间utugiqy61#
您可以将数据库实体模型与希望在前端显示的模型分开。将需要并希望包含到新前端模型中的实体模型的特性Map。
不实现新模型的更快方法是使用匿名对象,如:
如果你的实体类中真的有LazyLoader属性(例如注入ILazyLoader,如本文所述),您可以改为使用JsonIgnore attribtue来装饰它。
aydmsdu92#
您可以通过迭代
JObject
的JProperty
来从json中删除空的Object
和Array
,如下所示lazyLoader
对象,那么在上面的代码中使用下面的行。amrnrhlw3#
在Entity Framework中,如果有一个对象的一个或多个属性使用延迟加载,请使用GetType(). Name检查其运行时类型名称。例如,对于Car类的对象,您会注意到运行时类型实际上是名为CarProxy的东西,它是Entity Framework使用反射创建的临时内存类型。这个“假”代理类的基类是Car,并且具有所有原始的Car属性,但包括一个额外的名为 LazyLoader 的属性,用于可能需要它的属性。
如果你进一步检查这个“fake”CarProxy类型,你还会看到Assembly.IsDynamic = true,这表明这个类是用反射动态创建的(参见documentation):
幸运的是,Newtonsoft.json在**JsonConvert.SerializeObject()**方法上有一个覆盖,它允许我们提供一个基类型,这样得到的JSON就不会包含该类型中不存在的属性。因此,要消除 LazyLoader 属性,只需提供对象的BaseType作为类型参数:
为了确保序列化时不会得到任何循环引用循环(使用延迟加载时可能性很高),请使用以下设置调用序列化器:
**注意:当序列化器遍历对象时,这可能只在第一层深度上工作。如果您提供给序列化程序的对象还有更多的延迟加载子属性,则可能会再次出现“LazyLoader”属性。我还没有测试过,所以我不能确定。
ql3eal8s4#
基于a suggestion at EFCore repos和another SO answer it referenced,我将把这种替代方法留给那些只想摆脱lazyLoader属性的人
创建CustomContractResolver.cs
并修改Startup.cs,
ConfigureServices
方法以使用ContractResolver