C# EF Core使用LINQ自定义JSON序列化
我正在为.NETCore中的API构建一个演示,并构建一个需要通过一系列LINQ查询构建的嵌套JSON对象 我当前的问题是,当我得到大约4层深度时,我想定制实际序列化的内容,更具体地说,我想“不包括”特定于此查询的导航属性,但不是用于一般目的,仅用于此特定查询C# EF Core使用LINQ自定义JSON序列化,c#,json,linq,asp.net-core,ef-core-3.0,C#,Json,Linq,Asp.net Core,Ef Core 3.0,我正在为.NETCore中的API构建一个演示,并构建一个需要通过一系列LINQ查询构建的嵌套JSON对象 我当前的问题是,当我得到大约4层深度时,我想定制实际序列化的内容,更具体地说,我想“不包括”特定于此查询的导航属性,但不是用于一般目的,仅用于此特定查询 我的第一个想法是做一个DTO,但这似乎是一个不必要的额外模型,仅针对这一个特定的情况…我想直接与LINQ合作,以操纵我的结果 我已经在Startup.cs文件中添加了以下内容以避免循环: services.AddControllers()
我的第一个想法是做一个DTO,但这似乎是一个不必要的额外模型,仅针对这一个特定的情况…我想直接与LINQ合作,以操纵我的结果 我已经在Startup.cs文件中添加了以下内容以避免循环:
services.AddControllers().AddNewtonsoftJson(选项=>
options.SerializerSettings.ReferenceLoopHandling=Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
我目前有5个模型在运行,如下所示:
{
"id": 1,
"name": "Amanda's Hotel",
"streetAddress": "123 CandyCane Lane",
"city": "Seattle",
"state": "WA",
"phone": "123-456-8798",
"hotelRooms": [
{
"hotelID": 1,
"roomNumber": 101,
"roomID": 2,
"rate": 75,
"petFriendly": false,
"room": {
"id": 2,
"name": "Queen Suite",
"layout": 2,
"roomAmenities": [
{
"roomID": 2,
"amenitiesID": 1,
"amenity": {
"id": 1,
"name": "Coffee Maker"
}
}
],
"hotelRooms": []
}
},
{
"hotelID": 1,
"roomNumber": 123,
"roomID": 1,
"rate": 120,
"petFriendly": true,
"room": {
"id": 1,
"name": "Princess Suite",
"layout": 1,
"roomAmenities": [
{
"roomID": 1,
"amenitiesID": 1,
"amenity": {
"id": 1,
"name": "Coffee Maker"
}
},
{
"roomID": 1,
"amenitiesID": 2,
"amenity": {
"id": 2,
"name": "Mini Bar"
}
}
],
"hotelRooms": []
}
}
]
}
公共级酒店
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共字符串StreetAddress{get;set;}
公共字符串City{get;set;}
公共字符串状态{get;set;}
公用字符串电话{get;set;}
公共列表酒店房间{get;set;}
}
公共教室
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共布局{get;set;}
公共列表{get;set;}
公共列表酒店房间{get;set;}
}
公共客房
{
公共int HotelID{get;set;}
public int RoomNumber{get;set;}
public int RoomID{get;set;}
公共十进制率{get;set;}
公共布尔值{get;set;}
公共酒店{get;set;}
公共房间{get;set;}
}
公共设施
{
公共int ID{get;set;}
公共字符串名称{get;set;}
//导航属性
公共列表{get;set;}
}
公共教室设施
{
public int RoomID{get;set;}
公共int修正ID{get;set;}
公共房间{get;set;}
公共设施设施{get;set;}
}
在我的服务中,我有这样一种逻辑,实际上是在进行查询:
public异步任务GetById(int-id)
{
var hotel=wait_context.hotel.FindAsync(id);
//得到一份房间清单
var rooms=await\u context.HotelRooms.Where(r=>r.HotelID==id)
.包括(d=>d.Room)
.然后包括(a=>a.客房设施)
.然后包括(x=>x.Amency).toListSync();
hotel.HotelRooms=房间;
返回酒店;
}
电流输出为:
{
"id": 1,
"name": "Amanda's Hotel",
"streetAddress": "123 CandyCane Lane",
"city": "Seattle",
"state": "WA",
"phone": "123-456-8798",
"hotelRooms": [
{
"hotelID": 1,
"roomNumber": 101,
"roomID": 2,
"rate": 75.00,
"petFriendly": false,
"room": {
"id": 2,
"name": "Queen Suite",
"layout": 2,
"roomAmenities": [
{
"roomID": 2,
"amenitiesID": 1,
"amenity": {
"id": 1,
"name": "Coffee Maker",
"roomAmenities": [
{
"roomID": 1,
"amenitiesID": 1,
"room": {
"id": 1,
"name": "Princess Suite",
"layout": 1,
"roomAmenities": [
{
"roomID": 1,
"amenitiesID": 2,
"amenity": {
"id": 2,
"name": "Mini Bar",
"roomAmenities": []
}
}
],
"hotelRooms": [
{
"hotelID": 1,
"roomNumber": 123,
"roomID": 1,
"rate": 120.00,
"petFriendly": true
}
]
}
}
]
}
}
],
"hotelRooms": []
}
},
{
"hotelID": 1,
"roomNumber": 123,
"roomID": 1,
"rate": 120.00,
"petFriendly": true,
"room": {
"id": 1,
"name": "Princess Suite",
"layout": 1,
"roomAmenities": [
{
"roomID": 1,
"amenitiesID": 1,
"amenity": {
"id": 1,
"name": "Coffee Maker",
"roomAmenities": [
{
"roomID": 2,
"amenitiesID": 1,
"room": {
"id": 2,
"name": "Queen Suite",
"layout": 2,
"roomAmenities": [],
"hotelRooms": [
{
"hotelID": 1,
"roomNumber": 101,
"roomID": 2,
"rate": 75.00,
"petFriendly": false
}
]
}
}
]
}
},
{
"roomID": 1,
"amenitiesID": 2,
"amenity": {
"id": 2,
"name": "Mini Bar",
"roomAmenities": []
}
}
],
"hotelRooms": []
}
}
]
}
这对我来说太嵌套了,我希望“舒适性”对象中的内部“RoomCommunications”不包括在内。我希望我的对象看起来像这样:
{
"id": 1,
"name": "Amanda's Hotel",
"streetAddress": "123 CandyCane Lane",
"city": "Seattle",
"state": "WA",
"phone": "123-456-8798",
"hotelRooms": [
{
"hotelID": 1,
"roomNumber": 101,
"roomID": 2,
"rate": 75,
"petFriendly": false,
"room": {
"id": 2,
"name": "Queen Suite",
"layout": 2,
"roomAmenities": [
{
"roomID": 2,
"amenitiesID": 1,
"amenity": {
"id": 1,
"name": "Coffee Maker"
}
}
],
"hotelRooms": []
}
},
{
"hotelID": 1,
"roomNumber": 123,
"roomID": 1,
"rate": 120,
"petFriendly": true,
"room": {
"id": 1,
"name": "Princess Suite",
"layout": 1,
"roomAmenities": [
{
"roomID": 1,
"amenitiesID": 1,
"amenity": {
"id": 1,
"name": "Coffee Maker"
}
},
{
"roomID": 1,
"amenitiesID": 2,
"amenity": {
"id": 2,
"name": "Mini Bar"
}
}
],
"hotelRooms": []
}
}
]
}
有人对我如何使用EFCore和LINQ实现这一目标有任何指导吗?你可以查看这篇文章
我看到您已经实现了referenceloopHandling,但是即使使用它,您也只能将内部引用设为null,而不能从json中完全删除键值对>我的第一个想法是做一个DTO,这是正确的方法。事实上,我几乎要说的是,如果您可以帮助的话,您不应该从API返回EF模型(否则每次您更改数据模型时,您的API契约都会在不需要时更改)。啊,谢谢!你肯定是对的,DTO是最好的方法。你有没有尝试过不包括
舒适性asvar rooms=wait\u context.HotelRooms.Where(r=>r.HotelID==id)。包括(d=>d.rooms)。然后包括(a=>a.roomfacility.tolistsync()代码>?