EF Core 存储过程不同的返回结果

A19*_*919 5 c# entity-framework-core

我有这个存储过程

CREATE PROCEDURE [dbo].[GetBooksByAuthor2]
AS
    SELECT 
        books.Id, authors.Name AS Author, books.Name AS Book 
    FROM
        dbo.Authors authors
    INNER JOIN 
        dbo.AuthorsBooks authorsBooks ON authors.Id = authorsBooks.AuthorId
    INNER JOIN 
        dbo.Books books ON books.Id = authorsBooks.BookId
GO
Run Code Online (Sandbox Code Playgroud)

在 SQL Server Management Studio 中,结果如下所示:

Id| Author       | Book
--+--------------+----------
1 | FirstAuthor  | GoodBook1
2 | FirstAuthor  | GoodBook2
3 | FirstAuthor  | GoodBook3
1 | SecondAuthor | GoodBook1
3 | SecondAuthor | GoodBook3 
Run Code Online (Sandbox Code Playgroud)

在 EF Core 中,我为我的存储过程添加了一个视图模型

public class BookViewModel
{
    [Key]
    public int Id { get; set; }

    public string Author { get; set; }
    public string Book { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我还在上下文类中添加了这样的东西:

public partial class StrangeContext : DbContext
{
     public virtual DbSet<BookViewModel> Books2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后我在控制器操作中调用它

[HttpGet]
public JsonResult GetAuthors()
{
    var result = db.Books2.FromSql("GetBooksByAuthor2").ToList();
    return new JsonResult(result);
}
Run Code Online (Sandbox Code Playgroud)

Json的结果看起来像

[
    { "id": 1, "author":"FirstAuthor", "book":"GoodBook1"},
    { "id": 2, "author":"FirstAuthor", "book":"GoodBook2"},
    { "id": 3, "author":"FirstAuthor", "book":"GoodBook3"}, 
    { "id": 1, "author":"FirstAuthor", "book":"GoodBook1"}, 
    { "id": 3, "author":"FirstAuthor", "book":"GoodBook3"}
]
Run Code Online (Sandbox Code Playgroud)

我做错了什么?错误的视图模型?第二作者在哪里?

Rau*_*ian 5

您定义的Id你的BookViewModel作为重点,因此,实体框架缓存在第一时间将其与查询“FirstAuthor”Id1。第二次遇到Id1 时,它使用当前上下文并根据缓存的值填充实体。

这里的问题是你模棱两可的模型。怎么能FirstAuthorSecondAuthor两者都有Id= 1。

您可以删除模型中的Key属性,但它可能会导致混乱,无论您在何处显示这些结果,一旦您想要保存这些实体中的任何一个,您将获得不可预测的结果。

您也可以尝试,AsNotracking()但我强烈建议您不要这样做,因为一旦您尝试跟踪或保存更改,就会遇到麻烦。相反,调整您的存储过程以返回唯一行的唯一 ID。