如何使用实体框架保证与派生字段的一致代码

时间:2015-11-24 12:40:05

标签: c# .net entity-framework entity-framework-6

我有以下课程/表enter image description here

Apolices.CodRamos就在那张桌子里,因为它是一张钥匙。 Apolices.CodRamo必须等于Apolices.CodProduto.CodRamo以保持代码一致。

我认为我可以在我的Apolices Model类中解决这个问题:

public int CodRamo
    {
        get{ return Produtos.CodRamo; }
        set{ Produtos.CodRamo = value; }
    }

public virtual Produtos Produtos { get; set; }

但由于在未初始化时尝试使用虚拟字段,因此无法加载类的方式。

如果我创建一个新的Produtos,它会混淆CodProduto的关系。 Produto.CodProduto一直保持等于0 ......

如何解决此问题以获得一致的代码?

编辑: Bellow完整的代码:

public partial class Apolices
{
    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CodApolice { get; set; }

    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CodRamo
    {
        get{ return Produtos.CodRamo; }
        set{ Produtos.CodRamo = value; }
    }

    [StringLength(50)]
    public string Descricao { get; set; }

    public int? CodProduto { get; set; }

    public virtual Produtos Produtos { get; set; }

    public virtual Ramos Ramos { get; set; }
}


public partial class Produtos
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Produtos()
    {
        Apolices = new HashSet<Apolices>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CodProduto { get; set; }

    public int CodRamo { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Apolices> Apolices { get; set; }

    public virtual Ramos Ramos { get; set; }
}


public partial class Ramos
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Ramos()
    {
        Apolices = new HashSet<Apolices>();
        Produtos = new HashSet<Produtos>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CodRamo { get; set; }

    [StringLength(50)]
    public string Descricao { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Apolices> Apolices { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Produtos> Produtos { get; set; }
}

public partial class ModelContext : DbContext
{
    public ModelContext()
        : base("name=ModelContext")
    {
    }

    public virtual DbSet<Apolices> Apolices { get; set; }
    public virtual DbSet<Produtos> Produtos { get; set; }
    public virtual DbSet<Ramos> Ramos { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Apolices>()
            .Property(e => e.Descricao)
            .IsUnicode(false);

        modelBuilder.Entity<Ramos>()
            .Property(e => e.Descricao)
            .IsUnicode(false);

        modelBuilder.Entity<Ramos>()
            .HasMany(e => e.Apolices)
            .WithRequired(e => e.Ramos)
            .WillCascadeOnDelete(false);
    }
}

2 个答案:

答案 0 :(得分:1)

问题在于您尝试在ApoliceProdutosRamos之间建立关系。但是,考虑到您的解释,您真正想要做的是ApoliceRelationshipOfProdutosRamos之间的关系。所以,表结构应该是这样的:

enter image description here

SQL代码:

create table Produtos (
    CodProduto int primary key not null identity(1,1),
    Descricao varchar(50) not null
)

create table Ramos (
    CodRamo int primary key not null identity(1,1),
    Descricao varchar(50) not null
)

create table ProdutosRamos (
    CodProduto int not null foreign key references Produtos(CodProduto),
    CodRamo int not null foreign key references Ramos (CodRamo),
    primary key (CodProduto, CodRamo)
)

create table Apolices (
    CodProduto int not null,
    CodRamo int not null,
    Descricao varchar(50) not null,
    primary key (CodProduto, CodRamo),
    foreign key (CodProduto, CodRamo) references ProdutosRamos (CodProduto, CodRamo)
)

然后,您必须在EntityFramework中进行一些更改:

public partial class Apolices
{
    [Key]
    [Column(Order = 0)]
    [ForeignKey("ProdutosRamos")]
    public int CodProduto { get; set; }

    [Key]
    [Column(Order = 1)]
    [ForeignKey("ProdutosRamos")]
    public int CodRamo
    {
        get; set;
    }

    [StringLength(50)]
    public string Descricao { get; set; }

    public virtual ProdutosRamos ProdutosRamos { get; set; }
}


public partial class Produtos
{  
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CodProduto { get; set; }

    [StringLength(50)]
    public string Descricao { get; set; }
}


public partial class Ramos
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CodRamo { get; set; }

    [StringLength(50)]
    public string Descricao { get; set; }
}

public partial class ProdutosRamos
{  
    [Key]
    public int CodProduto { get; set; }

    [Key]
    public int CodRamo { get; set; }

    [ForeignKey("CodProduto")]
    public virtual Produtos Produtos { get; set; }

    [ForeignKey("CodRamo")]
    public virtual Ramos Ramos { get; set; }
}

希望它有所帮助!

答案 1 :(得分:1)

问题是数据库不是正常形式(并不反映您所描述的内容)。

从Apolices导航到Produtos,您可以为单个Produtos记录获得更多Apolices记录。考虑表格Apolices,修复一个CodApolice(即AP1)你可以拥有(在3个不同的记录中)CodRamo R1,CodRamo R2和CodRamo R3每个人都有相同的P1 CodProduto。所以单个Productos可以有多个Ramo 此外,单个Produto与代码A1的Apolices相关联(Apolices表的pk是CodApolice和CodRamo)。这可以吗? 等等...