Andrew Kilburn
Andrew Kilburn

Reputation: 2251

How to gain access to table data through foreign key reference?

I have a statement in one of my entities which uses a foreign key to return an IEnumerable<CustomField>.

I have used LINQ in my repository to test the below method to see if it works and it does. But when I use the foreign key reference in the entity it returns null. Am I missing something here? How can I use a foreign key to gain access to the data in another entity.

Invoice entity:

[Table("vwinvoice")]
public class Invoice 
{
        [Key]
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
        public int Sys_InvoiceID { get; set; }
        [DisplayName("Inc.In Turnover")]
        public bool Turnover { get; set; }
        public int FK_StatusID { get; set; }
        [DisplayName("Invoice No.")]
        public string InvoiceNumber { get; set; }
        [DisplayName("Invoice Date")]
        public DateTime InvoiceDate { get; set; }
        [DisplayName("Document Type")]
        public string DocType { get; set; }
        [DisplayName("Supplier Invoice No.")]
        [Column("SupplierInvoiceNumber")]
        public string SuppInvNumber { get; set; }
        public int FK_SupplierID { get; set; }
        [DisplayName("Account Number")]
        public string AccountNumber { get; set; }
        [DisplayName("Order Number")]
        public string OrderNumber { get; set; }
        [DisplayName("Order Date")]
        public DateTime? OrderDate { get; set; }
        [DisplayName("Currency Code_Doc")]
        public string CurrencyCode_Doc { get; set; }
        [DisplayName("Net Amount_Doc")]
        public decimal? NetAmount_Doc { get; set; }
        [DisplayName("VAT Amount_Doc")]
        public decimal? VATAmount_Doc { get; set; }
        [DisplayName("Gross Amount_Doc")]
        [Required]
        public decimal? GrossAmount_Doc { get; set; }
        [DisplayName("Currency Code_Home")]
        public string CurrencyCode_Home { get; set; }
        [DisplayName("Net Amount_Home")]
        public decimal? NetAmount_Home { get; set; }
        [DisplayName("VAT Amount_Home")]
        public decimal? VATAmount_Home { get; set; }
        [DisplayName("Gross Amount_Home")]
        public decimal? GrossAmount_Home { get; set; }
        [DisplayName("Payment Reference")]
        public string PaymentReference { get; set; }
        [DisplayName("Supplier")]
        public string AccountName { get; set; }
        [DisplayName("Status")]
        public string StatusName { get; set; }
        [DisplayName("Auditor Comments")]
        public string AuditorComments { get; set; }
        [DisplayName("Reviewer Comments")]
        public string ReviewerComments { get; set; }
        [DisplayName("Data Source")]
        [Required]
        public string DataOrigin { get; set; }
        public int DetailLineCount { get; set; }

        public IEnumerable<CustomField> ClientData {
            get {
//Use the CustomFields foreign key to gain access to the data returns null.
                return GetCustomFieldData(this.CustomFields.Select(r => r));
            }
        }

        private IEnumerable<CustomField> GetCustomFieldData(IEnumerable<Entities.CustomFields> enumerable) {
            return (from f in enumerable
                    select new CustomField {
                        Name = f.FK_CustomHeader,
                        Value = f.Value
                    });
        }

        //Custom Field Additions
        public virtual ICollection<CustomFields> CustomFields { get; set; }
}

CustomFields entity:

[Table("tblCustomFields")]
public class CustomFields 
{
        [Key]
        public int ID { get; set; }

        public int? FK_SysInvoiceID { get; set; }

        [StringLength(255)]
        public string FK_CustomHeader { get; set; }

        [StringLength(255)]
        public string Value { get; set; }

        public virtual Invoice Invoices { get; set; }

        public virtual CustomFieldHeaders CustomFieldHeaders { get; set; }
}

I also cannot place a breakpoint in the get statement to see what happens, why is this? It just skips over the breakpoint whenever I try to return a list of Invoices, which can be seen here:

public IQueryable<Invoice> Invoices 
{
    get 
    {
        var x = _ctx.Invoices.ToList();
        return _ctx.Invoices;
    }
}

Upvotes: 0

Views: 716

Answers (1)

strickt01
strickt01

Reputation: 4048

You are using the virtual keyword when declaring your CustomFields property. As such it will be lazy loaded. If you want the property to be populated once returned from the repository you will need to explicitly Include the table in your method:

var x = _ctx.Invoices.Include(i => i.CustomFields).ToList();
return _ctx.Invoices;

Or you can remove the virtual keyword and the property will always be populated, with the consequent performance hit of the database join and the extra data being returned whenever you access Invoices.

Upvotes: 1

Related Questions