简体   繁体   中英

Using Include in Entity Framework Core to retrieve related data where the field name doesn't match the primary key

I'm very new to EF (using Core as a first up) and have been battling with a problem for a while now.

Briefly, I have 2 entities that relate to each other on a one-to-one basis. In the one example, which works fine, I have an "parent" entity related to a "child" entity such as below

[Table("Attribute", Schema = "dbo")]
public class Attribute
{
    public Attribute()
    {
    }
    [Key, Column(Order = 1)] 
    public Guid EntityColumnRefNo {get; set;}
    public string  PhysicalName {get; set;}
    public string  Caption {get; set;}
    public AttributeType AttributeType {get; set;}
}

[Table("AttributeType", Schema = "dbo")]
public class AttributeType
{

    public AttributeType()
    {
    }
    [Key, Column(Order = 1)] 
    public Guid AttributeTypeRefNo {get; set;}
    public string  UserRefCode {get; set;}
    public string  Description {get; set;}
}

The physical column name on the Attribute table on the database for the AttributeTypeRefNo is exactly that - AttributeTypeRefNo (Not sure if that has relevance). When returning the Attribute model using the following code

var res = db?.Attribute
    .Where(x => x.EntityRefNo == entityrefNo)
    .Include(c => c.AttributeType)

It works perfectly fine. The Attribute returns with the populated AttributeType.

My problem occurs when adding another Model above Attribute, and reference Attribute twice.

[Table("Relations", Schema = "dbo")]
public class Relations
{

    public Relations()
    {
    }
    [Key, Column(Order = 1)] 
    public Guid GenRelRefNo {get; set;}
    public Attribute EntityColumnTo { get; set; }
    public Attribute EntityColumnFrom { get; set; }
    public string  CollaborationCaption {get; set;}
    public string  CollaborationTooltip {get; set;}
}

The Relations Model contains 2 occurrences of Attributes, each referring to a different attribute. The column names on the Table in the database are as they are on the model - EntityColumnTo and EntityColumnFrom. The code I'm using the Relations Model is

var res = db?.Relations
            .Include(c => c.EntityColumnTo)
            .Include(c => c.EntityColumnFrom)
            .Where(x => x.EntityColumnTo.EntityRefNo == entityrefNo 
               || x.EntityColumnFrom.EntityRefNo == entityrefNo).ToList();

This call doesn't work, I get the errors below, moaning about invalid column names.

System.Data.SqlClient.SqlException occurred
  HResult=0x80131904
  Message=Invalid column name 'EntityColumnFromEntityColumnRefNo'.
Invalid column name 'EntityColumnToEntityColumnRefNo'.
Invalid column name 'EntityColumnToEntityColumnRefNo'.
Invalid column name 'EntityColumnFromEntityColumnRefNo'.
Invalid column name 'EntityColumnFromEntityColumnRefNo'.
Invalid column name 'EntityColumnToEntityColumnRefNo'.
Invalid column name 'EntityColumnFromEntityColumnRefNo'.
Invalid column name 'EntityColumnToEntityColumnRefNo'.
  Source=.Net SqlClient Data Provider
  StackTrace:
<Cannot evaluate the exception stack trace>

So, what am I doing wrong? I have other examples that mirror then method I first described and they all work fine. I'm sure having 2 Declarations on the Relations model for the same Attributes type is the problem and needs some extra handling - how would the framework know what properties to bind where. I've hacked the code to make it work using extension methods and all sorts of other nonsense, but I can't believe that's the right way of doing things. Thanks in advance.

You should add Foreign Key properties to all your entities. EF supports not doing this, but it's more difficult. Once you have explicit ForeignKey properties, it's simple to decorate the model. EG

[Table("Relations", Schema = "dbo")]
public class Relations
{

    public Relations()
    {
    }
    [Key, Column(Order = 1)] 
    public Guid GenRelRefNo {get; set;}

    [ForeignKey("EntityColumnToRefNo")]
    public Attribute EntityColumnTo { get; set; }

    [ForeignKey("EntityColumnFromRefNo")]
    public Attribute EntityColumnFrom { get; set; }

    public Guid EntityColumnToRefNo { get; set; }
    public Guid EntityColumnFromRefNo { get; set; }

    public string  CollaborationCaption {get; set;}
    public string  CollaborationTooltip {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