EF Core хранимая процедура, отличающаяся от возвращаемого результата - PullRequest
3 голосов
/ 12 мая 2019

У меня есть эта хранимая процедура

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

В SQL Server Management Studio результат выглядит следующим образом:

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

В EF Core я добавил модель представления для своей хранимой процедуры

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

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

и я также добавил что-то подобное в класс контекста:

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

Затем я вызываю его в действии контроллера

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

Результат просмотра 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"}
]

Что я делаю не так?Неправильная ViewModel?Где Второй Автор?

Ответы [ 2 ]

4 голосов
/ 12 мая 2019

Вы определили Id вашего BookViewModel как Key , и поэтому Entity Framework кэширует первый раз, если запрашивает у FirstAuthor значение Id из 1 *.1007 *.Во второй раз, когда он встречает Id 1, он использует текущий контекст и заполняет сущность на основе кэшированного значения.

Проблема здесь в вашей двусмысленной модели.Как FirstAuthor и SecondAuthor оба могут иметь Id = 1.

Вы можете удалить атрибут Key в вашей модели, но это может привести к путанице, где бы вы ни отображалисьэти результаты, и как только вы захотите сохранить любую из этих сущностей, вы получите непредсказуемые результаты.

Вы также можете попробовать AsNotracking(), но я настоятельно рекомендую, поскольку у вас будут проблемы, когда вы попытаетесь отследитьили сохранить изменения.Вместо этого настройте хранимую процедуру так, чтобы она возвращала уникальные Id s для уникальных строк.

1 голос
/ 12 мая 2019

Вы определили Id в BookViewModel классе как ключ, но вы передаете неуникальные значения:

добавьте authorsBooks.Id в ваш запрос SQL и передайте его [Key] вВы классифицируете и определяете другое поле для отображения BookId как в запросе, так и в классе.

Код будет выглядеть так:

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

    public string Author { get; set; }

    public int BookId { get; set; }

    public string Book { get; set; }
}

И вам лучше написать свою процедуру следующим образом:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...