将一对多关系映射到没有键的现有数据库视图

本文关键字:数据库 视图 一对多 关系 映射 | 更新日期: 2023-09-27 18:14:43

我需要在两个类之间创建一对多的关系。数据库不包含主键或外键。所以我决定创建2个视图而不是3个表,视图也没有主/外键(改变数据库模式是不允许的)

观点

[Table("Barcode")]
public partial class Barcode
{
    [Column("_Barcode")]
    public string _Barcode { get; set; }
    [Column("_SkuRef")]
    [MaxLength(16)]
    public byte[] _SkuRef { get; set; }
    [Key]
    [Column("Id")]
    public long Id { get; set; }
    public string _SkuId { get; set; }
}

[Table("SKU")]
public partial class SKU
{
    [Column("_Code", Order = 0)]
    [StringLength(11)]
    public string _Code { get; set; }
    [Column("_Description", Order = 1)]
    [StringLength(150)]
    public string _Description { get; set; }
    [Column("_ProductId", Order = 2)]
    [StringLength(50)]
    public string _ProductId { get; set; }
    [Column("_Ref", Order = 3)]
    [MaxLength(16)]
    public byte[] _Ref { get; set; }
    [Key]
    [Column(Order = 4)]
    [StringLength(36)]
    public string Id { get; set; }
}

在这种情况下,我尝试使用类似

的东西
using (SkuContext db = new SkuContext())
        {
            var Skutable = db.SKUs;
            foreach(var s in Skutable)
            {
                Console.WriteLine(s.Id);
            }
        } 

运行良好。但是当我试图添加

 public partial class Barcode
 {
  ....
    [ForeignKey("_SkuId")]
    [Column("_SkuId")]
    [StringLength(36)]
    public string _SkuId { get; set; }
 }
 public partial class SKU
 {
  ....
    public IEnumerable<Barcode> Barcodes;
 }

我面对属性'_SkuId'不能配置为导航属性';错误。我的问题是如何做正确的事?如何在这样的两个类之间创建关系?

将一对多关系映射到没有键的现有数据库视图

我认为您可以在您的SKUBarcode视图之间创建一对多关系,其中一个SKU有许多条形码,如果它是表,您将以相同的方式这样做。使用Fluent API配置SKU和Barcode之间的一对多关系:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    // one-to-many relationship
    // _SkuId foreign key in Barcode
    modelBuilder.Entity<Barcode>()
        .HasRequired(c => c.SKU)
        .WithMany(t => t.Barcodes)
        .Map(m => m.MapKey("_SkuId"));
}

像这样更新你的类:

[Table("Barcode")]
public partial class Barcode
{
    [Column("_Barcode")]
    public string _Barcode { get; set; }
    [Column("_SkuRef")]
    [MaxLength(16)]
    public byte[] _SkuRef { get; set; }
    [Key]
    [Column("Id")]
    public long Id { get; set; }
    // need to comment this out
    //[Column("_SkuId")]
    //[StringLength(36)]
    //public string _SkuId { get; set; }

    public virtual SKU SKU { get; set; }
}
[Table("SKU")]
public partial class SKU
{
    [Column("_Code", Order = 0)]
    [StringLength(11)]
    public string _Code { get; set; }
    [Column("_Description", Order = 1)]
    [StringLength(150)]
    public string _Description { get; set; }
    [Column("_ProductId", Order = 2)]
    [StringLength(50)]
    public string _ProductId { get; set; }
    [Column("_Ref", Order = 3)]
    [MaxLength(16)]
    public byte[] _Ref { get; set; }
    [Key]
    [Column(Order = 4)]
    [StringLength(36)]
    public string Id { get; set; }
    public virtual ICollection<Barcode> Barcodes { get; set; }
}

您得到错误,因为您的表不包含外键。外键属性没有帮助,因为数据库中没有这样的关系。

如果您正在使用ORM,如实体框架,解决方案将是编写一个存储过程,并使EF与它一起工作。

另一种方法是使用System.Data.SqlClient中的类通过特定的读取,写入等实现自己的业务逻辑。

所以我认为在你简单的情况下不需要这样的练习。但是,如果你只是用这种直接的方式,不改变表格,准备好大量的文档。