简体   繁体   English

在继承TPC中具有相同主键的实体

[英]Entity with same primary key in an inheritance TPC

I create a website in ASP.NET MVC 4 and i have this error that i can't understand : 我在ASP.NET MVC 4中创建了一个网站,但出现了我无法理解的错误:

All objects EntitySet 'DataContext.Strategies' must have unique primary keys. 所有对象EntitySet'DataContext.Strategies'必须具有唯一的主键。 However, an instance of type 'AuctionSelling' and an instance of type 'DirectSelling' have the same primary key value, 'EntitySet = Strategies; 但是,类型'AuctionSelling'的实例和类型'DirectSelling'的实例具有相同的主键值,'EntitySet = Strategies; Id = 0'. ID = 0'。

So this is a problem of primary key but i don't understand why it happens. 所以这是主键的问题,但我不明白为什么会发生。

I use the strategy TPC for my inheritance and this is my class : 我使用策略TPC进行继承,这是我的课程:

public abstract class SellingStrategy
{
    public long Id { get; set; }
    public DateTime SoldDate { get; set; }
    public abstract float getSoldPrice();
}


public class DirectSelling : SellingStrategy
{
    public float SoldPrice { get; set; }

    public override float getSoldPrice()
    {
        return SoldPrice;
    }
}


public class AuctionSelling : SellingStrategy
{
    public float BasePrice { get; set; }
    public DateTime EndOfAuction { get; set; }

    public override float getSoldPrice()
    {
        return BasePrice;
    }
}

And this is my context : 这是我的上下文:

public class DataContext : DbContext
{
    public DbSet<Article> Articles { get; set; }
    public DbSet<Utilisateur> Utilisateurs { get; set; }
    public DbSet<Adresse> Adresses { get; set; }

    public DbSet<SellingStrategy> Strategies { get; set; }

    public DataContext() : this ("DBAchatVente")
    {
    }

    public DataContext(string connectionString)
        : base(connectionString)
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Article>().HasKey<long>(a => a.Id);
        modelBuilder.Entity<Article>().Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Article>().Property(a => a.Nom).IsRequired();
        modelBuilder.Entity<Article>().Property(a => a.Description).IsRequired();
        modelBuilder.Entity<Article>().Property(a => a.UrlImage).IsRequired();

        modelBuilder.Entity<Article>().Ignore(a => a.IdVendeur);
        modelBuilder.Entity<Article>().Ignore(a => a.MailVendeur);
        modelBuilder.Entity<Article>().Ignore(a => a.MotDePasseVendeur);
        modelBuilder.Entity<Article>().Ignore(a => a.AdresseLivraisonVendeur);
        modelBuilder.Entity<Article>().Ignore(a => a.AdressePaiementVendeur);
        modelBuilder.Entity<Article>().Ignore(a => a.NomVendeur);
        modelBuilder.Entity<Article>().Ignore(a => a.PrenomVendeur);

        modelBuilder.Entity<Article>().Ignore(a => a.IdAcheteur);
        modelBuilder.Entity<Article>().Ignore(a => a.MailAcheteur);
        modelBuilder.Entity<Article>().Ignore(a => a.MotDePasseAcheteur);
        modelBuilder.Entity<Article>().Ignore(a => a.AdresseLivraisonAcheteur);
        modelBuilder.Entity<Article>().Ignore(a => a.AdressePaiementAcheteur);
        modelBuilder.Entity<Article>().Ignore(a => a.NomAcheteur);
        modelBuilder.Entity<Article>().Ignore(a => a.PrenomAcheteur);

        modelBuilder.Entity<Article>().HasOptional<Utilisateur>(u => u.UserAcheteur).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Article>().HasRequired<Utilisateur>(u => u.UserVendeur).WithMany().WillCascadeOnDelete(false);

        modelBuilder.Entity<Article>().HasRequired<SellingStrategy>(a => a.Strategy).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<SellingStrategy>().Property(s => s.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        modelBuilder.Entity<AuctionSelling>().HasKey<long>(s => s.Id);            
        modelBuilder.Entity<AuctionSelling>().Map(m => {
            m.MapInheritedProperties();
            m.ToTable("AuctionSelling");
        });
        modelBuilder.Entity<DirectSelling>().HasKey<long>(s => s.Id);   
        modelBuilder.Entity<DirectSelling>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("DirectSelling");
        });
        modelBuilder.Entity<SellingStrategy>().Property<DateTime>(s => s.SoldDate).HasColumnName("DateVente").HasColumnType("datetime2").IsOptional();


        modelBuilder.Entity<Adresse>().HasKey<long>(a => a.Id);
        modelBuilder.Entity<Adresse>().Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Adresse>().Property(a => a.Rue).IsRequired();
        modelBuilder.Entity<Adresse>().Property<long>(a => a.Numero).IsRequired();
        modelBuilder.Entity<Adresse>().Property(a => a.Localite).IsRequired();
        modelBuilder.Entity<Adresse>().Property(a => a.Pays).IsRequired();

        modelBuilder.Entity<Utilisateur>().HasKey<long>(u => u.Id);
        modelBuilder.Entity<Utilisateur>().Property(u => u.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Utilisateur>().Property(u => u.Nom).IsRequired();
        modelBuilder.Entity<Utilisateur>().Property(u => u.Prenom).IsRequired();
        modelBuilder.Entity<Utilisateur>().Property(u => u.Mail).IsRequired();
        modelBuilder.Entity<Utilisateur>().Property(u => u.MotDePasse).IsRequired();

        modelBuilder.Entity<Utilisateur>().Ignore(u => u.RuePaiement);
        modelBuilder.Entity<Utilisateur>().Ignore(u => u.NumeroPaiement);
        modelBuilder.Entity<Utilisateur>().Ignore(u => u.LocalitePaiement);
        modelBuilder.Entity<Utilisateur>().Ignore(u => u.PaysPaiement);

        modelBuilder.Entity<Utilisateur>().Ignore(u => u.RueLivraison);
        modelBuilder.Entity<Utilisateur>().Ignore(u => u.NumeroLivraison);
        modelBuilder.Entity<Utilisateur>().Ignore(u => u.LocaliteLivraison);
        modelBuilder.Entity<Utilisateur>().Ignore(u => u.PaysLivraison);

        modelBuilder.Entity<Utilisateur>().HasRequired<Adresse>(a => a.AdresseLivraison).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Utilisateur>().HasRequired<Adresse>(a => a.AdressePaiement).WithMany().WillCascadeOnDelete(false);
    }
}

The exception occurs when i try to get my articles, there is 2 articles which have the same ID for the strategy, even if each strategy is in a different table. 当我尝试获取文章时会发生例外,即使每个策略都在不同的表中,也存在2个具有相同ID的策略文章。

using (DataContext context = new DataContext(connexion))
        {
            var con = from article in context.Articles.Include("UserVendeur").Include("UserAcheteur").Include("Strategy")
                      select article;
            listeArticle = con.ToList<Article>();
        }

This is the line 这是线

listeArticle = con.ToList<Article>();

that provoke the error. 引发错误。

I think that the answer is here : https://msdn.microsoft.com/en-us/data/jj591617.aspx#2.6 我认为答案在这里: https : //msdn.microsoft.com/zh-cn/data/jj591617.aspx#2.6

Basically you can't have two objects of the same type (here your base class) with the same PK. 基本上,您不能拥有两个具有相同PK的相同类型的对象(此处是您的基类)。

To achieve this you have to setup the identities of the table AuctionSelling and DirectSelling in the database with different seeds (0 and Int32.MinValue for example). 为此,您必须在数据库中使用不同的种子(例如0和Int32.MinValue)设置表AuctionSelling和DirectSelling的标识。

In sql server the needed command is : DBCC CHECKIDENT (DirectSelling, RESEED, 1000000000) 在sql server中,所需命令为:DBCC CHECKIDENT(DirectSelling,RESEED,1000000000)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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