简体   繁体   English

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

[英]EF Core stored procedure different returning result

I have this stored procedure 我有这个存储过程

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

In SQL Server Management Studio, result looks like this: 在SQL Server Management Studio中,结果如下所示:

Id| Author       | Book
--+--------------+----------
1 | FirstAuthor  | GoodBook1
2 | FirstAuthor  | GoodBook2
3 | FirstAuthor  | GoodBook3
1 | SecondAuthor | GoodBook1
3 | SecondAuthor | GoodBook3 

In EF Core I added a view model for my stored procedure 在EF Core中,我为我的存储过程添加了一个视图模型

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

    public string Author { get; set; }
    public string Book { get; set; }
}

and I also added something like this to the context class: 我还在上下文类中添加了这样的内容:

public partial class StrangeContext : DbContext
{
     public virtual DbSet<BookViewModel> Books2 { get; set; }
}

Then I invoke it in a controller action 然后我在控制器动作中调用它

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

Result of Json look like 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"}
]

What I am doing wrong? 我做错了什么? Wrong ViewModel? 错误的ViewModel? Where is SecondAuthor? SecondAuthor在哪里?

You defined the Id of your BookViewModel as the Key and as such, Entity Framework caches the first time if queries the 'FirstAuthor' with the Id of 1 . 您将BookViewModelId定义为Key ,因此,如果查询Id1的'FirstAuthor',Entity Framework将首次缓存。 The second time it encounters the Id 1, it uses the current context and fills the entity based on the cached value. 第二次遇到Id 1时,它使用当前上下文并根据缓存的值填充实体。

The problem here is your equivocal model. 这里的问题是你的模棱两可的模型。 How can FirstAuthor and SecondAuthor both have the Id = 1. FirstAuthorSecondAuthor如何都具有Id = 1。

You could remove the Key attribute in your model, but it might lead to confusion, wherever you display these results and once you will want to save any of these entities, you will get unpredictable results. 您可以删除模型中的Key属性,但这可能会导致混淆,无论您在何处显示这些结果,一旦您想要保存任何这些实体,您将获得不可预测的结果。

You could also try AsNotracking() but I would strongly advise against, as you will have troubles once you try to track or save changes. 您也可以尝试AsNotracking()但我强烈建议您反对,因为一旦您尝试跟踪或保存更改,您将遇到麻烦。 Instead adjust your stored procedure to return unique Id s for unique rows. 而是调整存储过程以返回唯一行的唯一Id

You've defined Id in BookViewModel class as a key but you're passing non-unique values: 您已将BookViewModel类中的Id定义为键,但您传递的是非唯一值:

add authorsBooks.Id to your SQL query and pass it to [Key] in you class and define another field to display BookId in both your query and class. authorsBooks.Id添加到SQL查询中并将其传递给您的类中的[Key] ,并定义另一个字段以在查询和类中显示BookId

The code would be like this: 代码如下:

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

    public string Author { get; set; }

    public int BookId { get; set; }

    public string Book { get; set; }
}

And you'd better write your procedure like this: 你最好像这样编写你的程序:

ALTER PROCEDURE [dbo].[GetBooksByAuthor2]
AS
    SELECT 
        AB.Id AS id, B.Id AS bookId, 
        A.[Name] AS author, B.[Name] AS book 
    FROM
        dbo.AuthorsBooks AS AB
    INNER JOIN 
        dbo.Books B ON AB.BookId = B.Id
    INNER JOIN 
        dbo.Authors A ON A.Id = AB.AuthorId
GO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM