简体   繁体   中英

EF5 code first: database ok, queries incorrect

In a code first project (EF5, MVC4), I have an entity called Consult. It has a collection of notes, which are saved and retrieved correctly in its own table.

A Consult entity can be used to collect other Consult entities for feedback (functional requirement of the application). So a Consult has a navigation property Feedbacks, which is a list of FeedbackRelation entities, representing the selected Consult entities. This information is saved in a FeedbackRelation table, where each record contains the ID of the Consult that contains the collection, and the ID of the Consult that is part of the collection (and some simple housekeeping properties).

The Consult entity has been defined as:

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; }
}

And the FeedbackRelation entity looks like this:

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; }
}

Some simple (bool, string) properties have been left out for clarity.

Creating a Consult, and adding other Consult entities to the Feedbacks list is working. All data is correctly saved in the database.

Retrieving the Consult does not retrieve the Feedbacks. Feedbacks.Count is always zero.

I exemined the SQL sent to the server, when retrieving the Feedbacks. It looks like this:

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'

In a more readable form this is:

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

This should however be:

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

Executing this query against the database returns the expected result.

Why is EF using the ID of the parent record as a search argument on the child ID? I have given the attribute InverseProperty("Feedback") to indicate which foreign key belongs to the feedbacks.

You have specified that the Feedbacks navigation property has an InverseProperty in FeedbackRelation named Feedback , and you have specified that the Feedback property has a foreign key named FeedbackID . This means that when you want to retrieve Feedbacks it should retrieve them using FeedbackID . So I don't understand why you would expect it to use the ConsultID instead.

You seem to be missing a second navigation property in the Consult class, and I find the naming confusing. I would expect something like this:

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; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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