Първи код EF5: базата данни е наред, заявките са неправилни

В проект с първи код (EF5, MVC4) имам обект, наречен Consult. Има колекция от бележки, които се записват и извличат правилно в собствената му таблица.

Субект Consult може да се използва за събиране на други обекти Consult за обратна връзка (функционално изискване на приложението). Така Consult има свойство за навигация Feedbacks, което е списък от обекти FeedbackRelation, представляващи избраните обекти Consult. Тази информация се записва в таблица FeedbackRelation, където всеки запис съдържа ИД на Консулт, който съдържа колекцията, и ИД на Консулт, който е част от колекцията (и някои прости свойства за поддържане).

Субектът Consult е дефиниран като:

public class Consult
{
    public virtual Guid ID { get; set; }
    public virtual string Subject { get; set; }

    public virtual ICollection<Note> Notes { get; set; }

    [InverseProperty("Feedback")]
    public virtual ICollection<FeedbackRelation> Feedbacks { get; set; }
}

А обектът FeedbackRelation изглежда така:

public class FeedbackRelation
{
    public Guid ID { get; set; }
    [Required]
    public virtual Guid FeedbackID { get; set; }
    [Required]
    public virtual Guid ConsultID { get; set; }

    [ForeignKey("FeedbackID")]
    public virtual Consult Feedback { get; set; }

    [ForeignKey("ConsultID")]
    public virtual Consult Consult { get; set; }
}

Някои прости свойства (bool, string) са пропуснати за по-голяма яснота.

Създаването на консултация и добавянето на други обекти на консултация към списъка с обратна връзка работи. Всички данни са правилно записани в базата данни.

Извличането на консултацията не извлича обратната връзка. Броят на обратната връзка винаги е нула.

Проверих SQL, изпратен до сървъра, при извличане на обратната връзка. Изглежда така:

exec sp_executesql N'SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[FeedbackID] AS [FeedbackID], 
[Extent1].[ConsultID] AS [ConsultID], 
FROM [dbo].[FeedbackRelation] AS [Extent1]
WHERE [Extent1].[FeedbackID] = @EntityKeyValue1',N'@EntityKeyValue1 uniqueidentifier',@EntityKeyValue1='58429806-CE36-4FDE-AD79-07E0872E3735'

В по-разбираема форма това е:

select * from FeedbackRelation where FeedbackID = '58429806-CE36-4FDE-AD79-07E0872E3735'

Това обаче трябва да бъде:

select * from FeedbackRelation where ConsultID = '58429806-CE36-4FDE-AD79-07E0872E3735'

Изпълнението на тази заявка към базата данни връща очаквания резултат.

Защо EF използва идентификатора на родителския запис като аргумент за търсене на дъщерния идентификатор? Дадох атрибута InverseProperty("Feedback"), за да посоча кой външен ключ принадлежи към обратната връзка.


person Ge We    schedule 11.12.2013    source източник


Отговори (1)


Вие сте посочили, че свойството за навигация Feedbacks има InverseProperty в FeedbackRelation с име Feedback, и сте посочили, че свойството Feedback има външен ключ с име FeedbackID. Това означава, че когато искате да извлечете Feedbacks, той трябва да ги извлече с помощта на FeedbackID. Така че не разбирам защо бихте очаквали да използва ConsultID вместо това.

Изглежда, че ви липсва второ свойство за навигация в класа Consult и намирам именуването за объркващо. Бих очаквал нещо подобно:

public class Consult
{
    public virtual Guid ID { get; set; }

    //etc

    [InverseProperty("Feedback")]
    public virtual ICollection<FeedbackRelation> ChildFeedbacks { get; set; }

    [InverseProperty("Consult")]
    public virtual ICollection<FeedbackRelation> ParentFeedbacks { get; set; }
}
person Colin    schedule 11.12.2013
comment
Прав ли съм, ако обобщя вашите промени като: - преименувайте навигационното свойство Feedbacks в ChildFeedbacks; - добавяне на свойство за навигация ParentFeedbacks, с обратен атрибут на свойство Consult (не го добавих, защото смятах, че нямам нужда от него). Значи навигационното свойство ChildFeedbacks все още има Feedback като свое обратно свойство? Опитах това, без успех. - person Ge We; 12.12.2013
comment
Не съм сигурен какво очаквате да видите и какво не виждате. Нито разбирам връзката, която се опитвате да моделирате. Искате ли нещо подобно: stackoverflow.com/q/12252868/150342 - person Colin; 13.12.2013
comment
Да, горе-долу това е. Просто искам самата релация да има някои свойства, затова го дефинирах сам, вместо да го оставя на EF. Странно е, че генерираната база данни изглежда точно както очаквах, създаването и запазването на обекти работи според очакванията. Това е просто извличане на връзката, която не работи. - person Ge We; 13.12.2013