Reputation: 150
I have a 3rd party database I'm trying to integrate with EF Core and it uses strange composite columns instead of foreign keys. A relationship is defined by a "Parent_Table_Name" and "Parent_Id". They're not keys, just an nchar(20) that contains the table name and an int with the ID in that table respectively. Is there any way I can establish navigation properties between tables if they don't have foreign keys?
The provider is Microsoft SQL Server. Here are CREATE statements that describe the situation.
CREATE TABLE [ParentA] (Table_Name nchar(20), Id int)
CREATE TABLE [ParentB] (Table_Name nchar(20), Id int)
CREATE TABLE [ChildC] (Table_Name nchar(20), Id int, Parent_Table_Name nchar(20), Parent_Table_Id int)
Here is an image of some sample data given the above tables.
Upvotes: 0
Views: 99
Reputation: 30425
These are known as a polymorphic associations (feature request #757). There is currently no first-class support for it, but you can work around it:
class ParentA
{
public string Table_Name { get; set; }
public int Id { get; set; }
public ICollection<ChildC> ChildCs { get; set; }
}
class ParentB
{
public string Table_Name { get; set; }
public int Id { get; set; }
public ICollection<ChildC> ChildCs { get; set; }
}
class ChildC
{
public string Table_Name { get; set; }
public int Id { get; set; }
public int? ParentA_Id { get; set; }
public ParentA ParentA { get; set; }
public int? ParentB_Id { get; set; }
public ParentB ParentB { get; set; }
}
var childrenWithParents = dbContext.ChildCs
// TODO: You could also create a view in the database
// or use ToSqlQuery on modelBuilder
.FromSql(@"
SELECT Table_Name,
Id,
CASE
WHEN Parent_Table_Name = 'ParentA'
THEN Parent_Table_Id
END AS ParentA_Id,
CASE
WHEN Parent_Table_Name = 'ParentB'
THEN Parent_Table_Id
END AS ParentB_Id
FROM ChildC")
.Include(c => c.ParentA)
.Include(c => c.ParentB)
.ToList();
Upvotes: 2