Entity Framework 6 TPT and foreign keys












0















I'm stuck trying to get EF to work with foreign keys in a TPT scenario. I think it is complicated in that one table has a one to many relationship, and the other has a one to one relationship.



This code is boiled down to illustrate the problem (GitHub: https://github.com/Dash/EFTest for VS project).



When I create a foreign key in the base Persons table I get an error about the type not being matched:




Product: FromRole: NavigationProperty 'Product' is not valid. Type
'Buyer' of FromRole 'Product_Buyers_Target' in AssociationType
'Product_Buyers' must exactly match with the type 'Person' on which
this NavigationProperty is declared on.




To try and tackle this, I move the Product navigation property up to the children, but then I get an error due to the ProductId column not existing in the database - it is trying to look in the derived tables and not in the base table.



I'm not entirely clear how to resolve this problem and have been going around in circles and googling until my eyes bleed. Can anybody help?



Model



public abstract class Person
{
public int Id { get; set; }
public string Name { get; set; }

public virtual Product Product { get; set; }
}

public class Buyer : Person
{
public string ShipTo { get; set; }
}

public class Seller : Person
{
public int Rating { get; set; } = 0;
}

public class Product
{
public int Id { get; set; }

public string Description { get; set; }
public virtual Seller Seller { get; set; }
public virtual IList<Buyer> Buyers { get; set; }
}


Schema



public class ProductSchema : EntityTypeConfiguration<Product>
{
public ProductSchema()
{
HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(p => p.Description)
.HasMaxLength(256);

HasOptional(p => p.Seller)
.WithRequired(i => i.Product)
.Map(m => m.MapKey("ProductId"));

HasMany(p => p.Buyers)
.WithRequired(i => i.Product)
.Map(m => m.MapKey("ProductId"));
}
}

public class PersonSchema : EntityTypeConfiguration<Person>
{
public PersonSchema()
{
ToTable("Persons");

HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(p => p.Name)
.HasMaxLength(128);
}
}

public class SellerSchema : EntityTypeConfiguration<Seller>
{
public SellerSchema()
{
ToTable("Sellers");

HasKey(s => s.Id)
.Property(s => s.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(s => s.Rating);
}
}

public class BuyerSchema : EntityTypeConfiguration<Buyer>
{
public BuyerSchema()
{
ToTable("Buyers");

HasKey(b => b.Id)
.Property(b => b.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(b => b.ShipTo)
.HasMaxLength(256);
}
}


SQL



CREATE TABLE Products (
Id INT IDENTITY PRIMARY KEY,
[Description] nvarchar(256),
)

create table Persons (
Id int IDENTITY PRIMARY KEY,
[Name] nvarchar(128),
ProductId INT NOT NULL,
FOREIGN KEY (ProductId) REFERENCES Products(Id)
)

CREATE TABLE Buyers (
Id INT PRIMARY KEY,
ShipTo nvarchar(256)
)

CREATE TABLE Sellers (
Id INT PRIMARY KEY,
Rating INT NOT NULL DEFAULT 0
)

DECLARE @ProductId int;
INSERT INTO Products ([Description]) VALUES ('Widget');
SET @ProductId = @@IDENTITY;

INSERT INTO Persons ([Name], ProductId) VALUES ('Bob the seller', @ProductId);
INSERT INTO Sellers (Id, Rating) VALUES (@@IDENTITY, 0);

INSERT INTO Persons ([Name], ProductId) VALUES ('Bert the buyer', @ProductId);
INSERT INTO Buyers (Id, ShipTo) VALUES (@@IDENTITY, 'Somewhere');









share|improve this question























  • add following property to Person class -> public int ProductId { get; set; }

    – Rudresha Parameshappa
    Nov 13 '18 at 16:04











  • This doesn't work. In order to use a named property as a foreign key, you need to use .WithMany().HasForeignKey(), which doesn't work with a one-to-one relationship (Seller). And functionally, is no different from using a hidden foreign key that I'm using at the moment with MapKey().

    – SirKumbskull
    Nov 15 '18 at 10:49
















0















I'm stuck trying to get EF to work with foreign keys in a TPT scenario. I think it is complicated in that one table has a one to many relationship, and the other has a one to one relationship.



This code is boiled down to illustrate the problem (GitHub: https://github.com/Dash/EFTest for VS project).



When I create a foreign key in the base Persons table I get an error about the type not being matched:




Product: FromRole: NavigationProperty 'Product' is not valid. Type
'Buyer' of FromRole 'Product_Buyers_Target' in AssociationType
'Product_Buyers' must exactly match with the type 'Person' on which
this NavigationProperty is declared on.




To try and tackle this, I move the Product navigation property up to the children, but then I get an error due to the ProductId column not existing in the database - it is trying to look in the derived tables and not in the base table.



I'm not entirely clear how to resolve this problem and have been going around in circles and googling until my eyes bleed. Can anybody help?



Model



public abstract class Person
{
public int Id { get; set; }
public string Name { get; set; }

public virtual Product Product { get; set; }
}

public class Buyer : Person
{
public string ShipTo { get; set; }
}

public class Seller : Person
{
public int Rating { get; set; } = 0;
}

public class Product
{
public int Id { get; set; }

public string Description { get; set; }
public virtual Seller Seller { get; set; }
public virtual IList<Buyer> Buyers { get; set; }
}


Schema



public class ProductSchema : EntityTypeConfiguration<Product>
{
public ProductSchema()
{
HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(p => p.Description)
.HasMaxLength(256);

HasOptional(p => p.Seller)
.WithRequired(i => i.Product)
.Map(m => m.MapKey("ProductId"));

HasMany(p => p.Buyers)
.WithRequired(i => i.Product)
.Map(m => m.MapKey("ProductId"));
}
}

public class PersonSchema : EntityTypeConfiguration<Person>
{
public PersonSchema()
{
ToTable("Persons");

HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(p => p.Name)
.HasMaxLength(128);
}
}

public class SellerSchema : EntityTypeConfiguration<Seller>
{
public SellerSchema()
{
ToTable("Sellers");

HasKey(s => s.Id)
.Property(s => s.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(s => s.Rating);
}
}

public class BuyerSchema : EntityTypeConfiguration<Buyer>
{
public BuyerSchema()
{
ToTable("Buyers");

HasKey(b => b.Id)
.Property(b => b.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(b => b.ShipTo)
.HasMaxLength(256);
}
}


SQL



CREATE TABLE Products (
Id INT IDENTITY PRIMARY KEY,
[Description] nvarchar(256),
)

create table Persons (
Id int IDENTITY PRIMARY KEY,
[Name] nvarchar(128),
ProductId INT NOT NULL,
FOREIGN KEY (ProductId) REFERENCES Products(Id)
)

CREATE TABLE Buyers (
Id INT PRIMARY KEY,
ShipTo nvarchar(256)
)

CREATE TABLE Sellers (
Id INT PRIMARY KEY,
Rating INT NOT NULL DEFAULT 0
)

DECLARE @ProductId int;
INSERT INTO Products ([Description]) VALUES ('Widget');
SET @ProductId = @@IDENTITY;

INSERT INTO Persons ([Name], ProductId) VALUES ('Bob the seller', @ProductId);
INSERT INTO Sellers (Id, Rating) VALUES (@@IDENTITY, 0);

INSERT INTO Persons ([Name], ProductId) VALUES ('Bert the buyer', @ProductId);
INSERT INTO Buyers (Id, ShipTo) VALUES (@@IDENTITY, 'Somewhere');









share|improve this question























  • add following property to Person class -> public int ProductId { get; set; }

    – Rudresha Parameshappa
    Nov 13 '18 at 16:04











  • This doesn't work. In order to use a named property as a foreign key, you need to use .WithMany().HasForeignKey(), which doesn't work with a one-to-one relationship (Seller). And functionally, is no different from using a hidden foreign key that I'm using at the moment with MapKey().

    – SirKumbskull
    Nov 15 '18 at 10:49














0












0








0








I'm stuck trying to get EF to work with foreign keys in a TPT scenario. I think it is complicated in that one table has a one to many relationship, and the other has a one to one relationship.



This code is boiled down to illustrate the problem (GitHub: https://github.com/Dash/EFTest for VS project).



When I create a foreign key in the base Persons table I get an error about the type not being matched:




Product: FromRole: NavigationProperty 'Product' is not valid. Type
'Buyer' of FromRole 'Product_Buyers_Target' in AssociationType
'Product_Buyers' must exactly match with the type 'Person' on which
this NavigationProperty is declared on.




To try and tackle this, I move the Product navigation property up to the children, but then I get an error due to the ProductId column not existing in the database - it is trying to look in the derived tables and not in the base table.



I'm not entirely clear how to resolve this problem and have been going around in circles and googling until my eyes bleed. Can anybody help?



Model



public abstract class Person
{
public int Id { get; set; }
public string Name { get; set; }

public virtual Product Product { get; set; }
}

public class Buyer : Person
{
public string ShipTo { get; set; }
}

public class Seller : Person
{
public int Rating { get; set; } = 0;
}

public class Product
{
public int Id { get; set; }

public string Description { get; set; }
public virtual Seller Seller { get; set; }
public virtual IList<Buyer> Buyers { get; set; }
}


Schema



public class ProductSchema : EntityTypeConfiguration<Product>
{
public ProductSchema()
{
HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(p => p.Description)
.HasMaxLength(256);

HasOptional(p => p.Seller)
.WithRequired(i => i.Product)
.Map(m => m.MapKey("ProductId"));

HasMany(p => p.Buyers)
.WithRequired(i => i.Product)
.Map(m => m.MapKey("ProductId"));
}
}

public class PersonSchema : EntityTypeConfiguration<Person>
{
public PersonSchema()
{
ToTable("Persons");

HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(p => p.Name)
.HasMaxLength(128);
}
}

public class SellerSchema : EntityTypeConfiguration<Seller>
{
public SellerSchema()
{
ToTable("Sellers");

HasKey(s => s.Id)
.Property(s => s.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(s => s.Rating);
}
}

public class BuyerSchema : EntityTypeConfiguration<Buyer>
{
public BuyerSchema()
{
ToTable("Buyers");

HasKey(b => b.Id)
.Property(b => b.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(b => b.ShipTo)
.HasMaxLength(256);
}
}


SQL



CREATE TABLE Products (
Id INT IDENTITY PRIMARY KEY,
[Description] nvarchar(256),
)

create table Persons (
Id int IDENTITY PRIMARY KEY,
[Name] nvarchar(128),
ProductId INT NOT NULL,
FOREIGN KEY (ProductId) REFERENCES Products(Id)
)

CREATE TABLE Buyers (
Id INT PRIMARY KEY,
ShipTo nvarchar(256)
)

CREATE TABLE Sellers (
Id INT PRIMARY KEY,
Rating INT NOT NULL DEFAULT 0
)

DECLARE @ProductId int;
INSERT INTO Products ([Description]) VALUES ('Widget');
SET @ProductId = @@IDENTITY;

INSERT INTO Persons ([Name], ProductId) VALUES ('Bob the seller', @ProductId);
INSERT INTO Sellers (Id, Rating) VALUES (@@IDENTITY, 0);

INSERT INTO Persons ([Name], ProductId) VALUES ('Bert the buyer', @ProductId);
INSERT INTO Buyers (Id, ShipTo) VALUES (@@IDENTITY, 'Somewhere');









share|improve this question














I'm stuck trying to get EF to work with foreign keys in a TPT scenario. I think it is complicated in that one table has a one to many relationship, and the other has a one to one relationship.



This code is boiled down to illustrate the problem (GitHub: https://github.com/Dash/EFTest for VS project).



When I create a foreign key in the base Persons table I get an error about the type not being matched:




Product: FromRole: NavigationProperty 'Product' is not valid. Type
'Buyer' of FromRole 'Product_Buyers_Target' in AssociationType
'Product_Buyers' must exactly match with the type 'Person' on which
this NavigationProperty is declared on.




To try and tackle this, I move the Product navigation property up to the children, but then I get an error due to the ProductId column not existing in the database - it is trying to look in the derived tables and not in the base table.



I'm not entirely clear how to resolve this problem and have been going around in circles and googling until my eyes bleed. Can anybody help?



Model



public abstract class Person
{
public int Id { get; set; }
public string Name { get; set; }

public virtual Product Product { get; set; }
}

public class Buyer : Person
{
public string ShipTo { get; set; }
}

public class Seller : Person
{
public int Rating { get; set; } = 0;
}

public class Product
{
public int Id { get; set; }

public string Description { get; set; }
public virtual Seller Seller { get; set; }
public virtual IList<Buyer> Buyers { get; set; }
}


Schema



public class ProductSchema : EntityTypeConfiguration<Product>
{
public ProductSchema()
{
HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(p => p.Description)
.HasMaxLength(256);

HasOptional(p => p.Seller)
.WithRequired(i => i.Product)
.Map(m => m.MapKey("ProductId"));

HasMany(p => p.Buyers)
.WithRequired(i => i.Product)
.Map(m => m.MapKey("ProductId"));
}
}

public class PersonSchema : EntityTypeConfiguration<Person>
{
public PersonSchema()
{
ToTable("Persons");

HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(p => p.Name)
.HasMaxLength(128);
}
}

public class SellerSchema : EntityTypeConfiguration<Seller>
{
public SellerSchema()
{
ToTable("Sellers");

HasKey(s => s.Id)
.Property(s => s.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(s => s.Rating);
}
}

public class BuyerSchema : EntityTypeConfiguration<Buyer>
{
public BuyerSchema()
{
ToTable("Buyers");

HasKey(b => b.Id)
.Property(b => b.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Property(b => b.ShipTo)
.HasMaxLength(256);
}
}


SQL



CREATE TABLE Products (
Id INT IDENTITY PRIMARY KEY,
[Description] nvarchar(256),
)

create table Persons (
Id int IDENTITY PRIMARY KEY,
[Name] nvarchar(128),
ProductId INT NOT NULL,
FOREIGN KEY (ProductId) REFERENCES Products(Id)
)

CREATE TABLE Buyers (
Id INT PRIMARY KEY,
ShipTo nvarchar(256)
)

CREATE TABLE Sellers (
Id INT PRIMARY KEY,
Rating INT NOT NULL DEFAULT 0
)

DECLARE @ProductId int;
INSERT INTO Products ([Description]) VALUES ('Widget');
SET @ProductId = @@IDENTITY;

INSERT INTO Persons ([Name], ProductId) VALUES ('Bob the seller', @ProductId);
INSERT INTO Sellers (Id, Rating) VALUES (@@IDENTITY, 0);

INSERT INTO Persons ([Name], ProductId) VALUES ('Bert the buyer', @ProductId);
INSERT INTO Buyers (Id, ShipTo) VALUES (@@IDENTITY, 'Somewhere');






c# inheritance entity-framework-6






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 16:00









SirKumbskullSirKumbskull

1




1













  • add following property to Person class -> public int ProductId { get; set; }

    – Rudresha Parameshappa
    Nov 13 '18 at 16:04











  • This doesn't work. In order to use a named property as a foreign key, you need to use .WithMany().HasForeignKey(), which doesn't work with a one-to-one relationship (Seller). And functionally, is no different from using a hidden foreign key that I'm using at the moment with MapKey().

    – SirKumbskull
    Nov 15 '18 at 10:49



















  • add following property to Person class -> public int ProductId { get; set; }

    – Rudresha Parameshappa
    Nov 13 '18 at 16:04











  • This doesn't work. In order to use a named property as a foreign key, you need to use .WithMany().HasForeignKey(), which doesn't work with a one-to-one relationship (Seller). And functionally, is no different from using a hidden foreign key that I'm using at the moment with MapKey().

    – SirKumbskull
    Nov 15 '18 at 10:49

















add following property to Person class -> public int ProductId { get; set; }

– Rudresha Parameshappa
Nov 13 '18 at 16:04





add following property to Person class -> public int ProductId { get; set; }

– Rudresha Parameshappa
Nov 13 '18 at 16:04













This doesn't work. In order to use a named property as a foreign key, you need to use .WithMany().HasForeignKey(), which doesn't work with a one-to-one relationship (Seller). And functionally, is no different from using a hidden foreign key that I'm using at the moment with MapKey().

– SirKumbskull
Nov 15 '18 at 10:49





This doesn't work. In order to use a named property as a foreign key, you need to use .WithMany().HasForeignKey(), which doesn't work with a one-to-one relationship (Seller). And functionally, is no different from using a hidden foreign key that I'm using at the moment with MapKey().

– SirKumbskull
Nov 15 '18 at 10:49












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284894%2fentity-framework-6-tpt-and-foreign-keys%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284894%2fentity-framework-6-tpt-and-foreign-keys%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Bressuire

Vorschmack

Quarantine