C# 控制器内部的Linq查询正在返回一个包含大量不需要的重复数据的数组
我对控制器如何返回结果有一个不寻常的问题 我在项目中使用.Net核心实体框架和SQL Server 返回的数据是AuthorList表中的一个Author行和AuthorBooks表中的3个Book行 这些书有一个authorId,它将它们链接到AuthorList表 在SQL中,我只需从AuthorBooks执行一个C# 控制器内部的Linq查询正在返回一个包含大量不需要的重复数据的数组,c#,entity-framework-core,dbcontext,C#,Entity Framework Core,Dbcontext,我对控制器如何返回结果有一个不寻常的问题 我在项目中使用.Net核心实体框架和SQL Server 返回的数据是AuthorList表中的一个Author行和AuthorBooks表中的3个Book行 这些书有一个authorId,它将它们链接到AuthorList表 在SQL中,我只需从AuthorBooks执行一个SELECT*,其中authorId='author\u 33' 这将返回AuthorBooks中的3行书籍 但是返回的JSON不是我所需要的 它列出了一个数组,每本书都包含一个a
SELECT*,其中authorId='author\u 33'
这将返回AuthorBooks中的3行书籍
但是返回的JSON不是我所需要的
它列出了一个数组,每本书都包含一个author数组。所以它复制了很多数据,比如:
[
{
"bookId": "1a",
"authorId": "author_33",
"bookText": "English_Variant1",
"author": {
"authorId": "author_33",
"authorText": "Bio Book 102",
"authorBooks": [
{
"bookId": "4a",
"authorId": "author_33",
"bookText": "English",
},
{
"bookId": "9a",
"authorId": "author_33",
"bookText": "Spanish",
}
]
}
},
{
"bookId": "4a",
"authorId": "author_33",
"bookText": "English",
"author": {
"authorId": "author_33",
"authorText": "Bio Book 102",
"authorBooks": [
{
"bookId": "1a",
"authorId": "author_33",
"bookText": "English_Variant1",
},
{
"bookId": "9a",
"authorId": "author_33",
"bookText": "Spanish",
}
]
}
},
{
"bookId": "9a",
"authorId": "author_33",
"bookText": "Spanish",
"author": {
"authorId": "author_33",
"authorText": "Bio Book 102",
"authorBooks": [
{
"bookId": "1a",
"authorId": "author_33",
"bookText": "English_Variant1",
},
{
"bookId": "4a",
"authorId": "author_33",
"bookText": "English",
}
]
}
}
]
但我需要它看起来像这样(注意它看起来有多漂亮):
返回JSON数据的控制器非常简单:
[HttpGet("GetBooksByAuthorId/{id}")]
public async Task<ActionResult<IEnumerable<AuthorBooks>>> GetBooksByAuthorId(Guid id)
{
var booksByAuthor = await _context.AuthorBooks.Where(q => q.AuthorId == id).ToListAsync();
return booksByAuthor;
}
这是我的AuthorList模型:
public partial class AuthorList
{
public Guid AuthorId { get; set; }
public string AuthorText { get; set; }
public virtual ICollection<AuthorBooks> AuthorBooks { get; set; }
}
modelBuilder.Entity<AuthorList>(entity =>
{
entity.HasKey(e => e.AuthorId);
entity.ToTable("AuthorList");
entity.Property(e => e.AuthorId)
.HasColumnName("AuthorId");
entity.Property(e => e.AuthorText)
.HasColumnName("AuthorText");
});
public部分类AuthorList
{
公共Guid AuthorId{get;set;}
公共字符串AuthorText{get;set;}
公共虚拟ICollection AuthorBooks{get;set;}
}
在我的数据库上下文中,它们如下所示:
[
{
"bookId": "1a",
"authorId": "author_33",
"bookText": "English_Variant1",
"author": {
"authorId": "author_33",
"authorText": "Bio Book 102",
"authorBooks": [
{
"bookId": "4a",
"authorId": "author_33",
"bookText": "English",
},
{
"bookId": "9a",
"authorId": "author_33",
"bookText": "Spanish",
}
]
}
},
{
"bookId": "4a",
"authorId": "author_33",
"bookText": "English",
"author": {
"authorId": "author_33",
"authorText": "Bio Book 102",
"authorBooks": [
{
"bookId": "1a",
"authorId": "author_33",
"bookText": "English_Variant1",
},
{
"bookId": "9a",
"authorId": "author_33",
"bookText": "Spanish",
}
]
}
},
{
"bookId": "9a",
"authorId": "author_33",
"bookText": "Spanish",
"author": {
"authorId": "author_33",
"authorText": "Bio Book 102",
"authorBooks": [
{
"bookId": "1a",
"authorId": "author_33",
"bookText": "English_Variant1",
},
{
"bookId": "4a",
"authorId": "author_33",
"bookText": "English",
}
]
}
}
]
作者书籍:
public partial class AuthorBooks
{
public Guid BookId { get; set; }
public Guid? AuthorId { get; set; }
public string BookText { get; set; }
public virtual AuthorList Author { get; set; }
}
modelBuilder.Entity<AuthorBooks>(entity =>
{
entity.HasKey(e => e.BookId);
entity.HasOne(d => d.Author)
.WithMany(p => p.AuthorBooks)
.HasForeignKey(d => d.AuthorId)
.OnDelete(DeleteBehavior.Cascade)
entity.ToTable("AuthorBooks");
entity.Property(e => e.BookId)
.HasColumnName("BookId");
entity.Property(e => e.AuthorId)
.HasColumnName("AuthorId");
entity.Property(e => e.BookText)
.HasColumnName("BookText");
});
modelBuilder.Entity(Entity=>
{
entity.HasKey(e=>e.BookId);
entity.HasOne(d=>d.Author)
.WithMany(p=>p.AuthorBooks)
.HasForeignKey(d=>d.AuthorId)
.OnDelete(DeleteBehavior.Cascade)
实体。ToTable(“AuthorBooks”);
entity.Property(e=>e.BookId)
.HasColumnName(“BookId”);
Property(e=>e.AuthorId)
.HasColumnName(“作者”);
属性(e=>e.BookText)
.HasColumnName(“BookText”);
});
作者列表:
public partial class AuthorList
{
public Guid AuthorId { get; set; }
public string AuthorText { get; set; }
public virtual ICollection<AuthorBooks> AuthorBooks { get; set; }
}
modelBuilder.Entity<AuthorList>(entity =>
{
entity.HasKey(e => e.AuthorId);
entity.ToTable("AuthorList");
entity.Property(e => e.AuthorId)
.HasColumnName("AuthorId");
entity.Property(e => e.AuthorText)
.HasColumnName("AuthorText");
});
modelBuilder.Entity(Entity=>
{
entity.HasKey(e=>e.authord);
实体。ToTable(“作者列表”);
Property(e=>e.AuthorId)
.HasColumnName(“作者”);
Property(e=>e.AuthorText)
.HasColumnName(“AuthorText”);
});
我认为这可能与我在模型中使用的ICollections有关
但是当我删除这些内容时,我的数据库上下文类中会出现错误
所以我有点被困在该怎么办的问题上
有并没有一种方法可以格式化它,这样它就不会复制大量的数据
谢谢 看起来您想返回根对象“AuthorList”,而不是“AuthorBooks”。在您的上下文中找到正确的作者并将其返回。看起来您想返回根对象“AuthorList”,而不是“AuthorBooks”。在您的上下文中找到正确的作者并将其返回。在控制器中,您可以查询包含相关书籍的作者,并相应地更改操作方法的返回类型以反映查询结果的类型-
[HttpGet("GetBooksByAuthorId/{id}")]
public async Task<ActionResult<AuthorList>> GetBooksByAuthorId(Guid id)
{
var authorWithBooks = await _context.AuthorLists
.Include(p=> p.AuthorBooks)
.FirstOrDefaultAsync(p=> p.AuthorId == id);
return authorWithBooks;
}
[HttpGet(“GetBooksByAuthorId/{id}”)]
公共异步任务GetBooksByAuthorId(Guid id)
{
var authorWithBooks=wait_context.AuthorLists
.Include(p=>p.AuthorBooks)
.FirstOrDefaultAsync(p=>p.AuthorId==id);
返回authorWithBooks;
}
这将匹配预期的JSON结果。在控制器中,您可以查询作者(包括相关书籍),并相应地更改操作方法的返回类型以反映查询结果的类型-
[HttpGet("GetBooksByAuthorId/{id}")]
public async Task<ActionResult<AuthorList>> GetBooksByAuthorId(Guid id)
{
var authorWithBooks = await _context.AuthorLists
.Include(p=> p.AuthorBooks)
.FirstOrDefaultAsync(p=> p.AuthorId == id);
return authorWithBooks;
}
[HttpGet(“GetBooksByAuthorId/{id}”)]
公共异步任务GetBooksByAuthorId(Guid id)
{
var authorWithBooks=wait_context.AuthorLists
.Include(p=>p.AuthorBooks)
.FirstOrDefaultAsync(p=>p.AuthorId==id);
返回authorWithBooks;
}
这将符合您预期的JSON结果。谢谢,但我确实想返回
AuthorBooks
byAuthor
。我理解这一点,但请查看您的有效负载。您直接序列化实体,导致“AuthorList”上的“AuthorBooks”集合被序列化(因此是重复的)。如果您返回“AuthorList”,您仍然可以得到“AuthorBooks”,但它们将是您想要的方式。试试看。谢谢。你是说这样做吗var booksByAuthor=wait _context.AuthorList.Where(q=>q.AuthorId==id).toListSync()
谢谢,但我确实想返回Author
作者的AuthorBooks
。我理解,但看看你的有效载荷。您直接序列化实体,导致“AuthorList”上的“AuthorBooks”集合被序列化(因此是重复的)。如果您返回“AuthorList”,您仍然可以得到“AuthorBooks”,但它们将是您想要的方式。试试看。谢谢。你是说这样做吗var booksByAuthor=wait _context.AuthorList.Where(q=>q.AuthorId==id).toListSync()代码>