EF Core 多对多相同对象出错
EF Core many to many of same object get error
我的情况是我有一个包含发票的系统,我可以为每张发票创建收据。
这种关系是多对多的,因为我可以为每张发票生成几张收据,而且当我创建收据时,我可以将它与几张发票相关联。
我有以下两个类:代表发票或收据的Document
,以及文件之间关联的DocumentOffset
。
public class Document
{
public Document()
{
}
public int ID { get; set; }
public string Reference { get; set; }
[Required]
public int? DocumentKind { get; set; }
[Required]
public long DocumentNum { get; set; }
[Required]
public DateTime? CreateDate { get; set; }
[Required]
public int? EntityID { get; set; }
public double TaxDeduction { get; set; }
public int Amount { get; set; }
public double SumBeforeDiscount
{
get
{
return Document2List.Sum(x => x.Sum);
}
}
public double DiscountPercent { get; set; }
public double DiscountValue
{
get
{
return SumBeforeDiscount * DiscountPercent / 100;
}
}
public double SumBeforeTax
{
get
{
return SumBeforeDiscount - DiscountValue;
}
}
public int TaxPercent { get; set; } = 17;
public double TaxValue
{
get
{
return SumBeforeTax * TaxPercent / 100;
}
}
public double Sum
{
get
{
if(DocumentKind == (int)Enums.DocumentKind.eDocumentKind.Reciept || DocumentKind == (int)Enums.DocumentKind.eDocumentKind.SupplierReciept)
{
return Document3List.Sum(x => x.Sum).Value;
}
return SumBeforeTax + TaxValue;
}
}
public double Paid
{
get
{
return Document3List.Where(x => x.Sum.HasValue).Sum(x => x.Sum.Value);
}
}
public double Balance
{
get
{
return Sum - Paid;
}
}
[Required]
public string Details { get; set; }
[Required]
public DateTime? Expire { get; set; }
public string VehicleID { get; set; }
public List<Document2> Document2List { get; set; } = new List<Document2>(); // Document items
public List<Document3> Document3List { get; set; } = new List<Document3>(); // Document payments when invoice and receipt produced in the same document
public Entity Entity { get; set; }
public ICollection<DocumentOffset> DocumentOffsets { get; set; } //this property
}
和
public class DocumentOffset
{
public int DocumentID { get; set; } //FK
public Document Document { get; set; }
public int RelatedDocumentID { get; set; } //FK
public Document RelatedDocument { get; set; }
public double Sum { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MissionCardWorker>().HasKey(x => new { x.MissionCardId, x.WorkerId });
modelBuilder.Entity<MissionCardItems>().HasKey(x => new { x.MissionCardId, x.ItemId });
modelBuilder.Entity<MissionCardMission>().HasKey(x => new { x.MissionCardId, x.MissionId });
modelBuilder.Entity<DocumentOffset>()
.HasOne(x => x.Document)
.WithMany(x => x.DocumentOffsets)
.HasForeignKey(x => x.RelatedDocumentID);
modelBuilder.Entity<DocumentOffset>()
.HasOne(x => x.RelatedDocument)
.WithMany(x => x.DocumentOffsets)
.HasForeignKey(x => x.DocumentID);
}
当我尝试添加迁移时出现以下错误:
Cannot create a relationship between 'Document.DocumentOffsets' and 'DocumentOffset.RelatedDocument', because there already is a relationship between 'Document.DocumentOffsets' and 'DocumentOffset.Document'. Navigation properties can only participate in a single relationship.
我应该怎么做才能解决这个问题?
谢谢:)
通常,对于多对多连接,您会遵循这样的模式;
public class Parent{
public int Id { get; set; }
public virtual ICollection<Join> Join { get; set; }
}
public class Join{
public int ParentId { get; set; }
public int ChildId { get; set; }
public virtual Parent Parent { get; set; }
public virtual Child Child { get; set; }
}
public class Child{
public int Id { get; set; }
public virtual ICollection<Join> Join { get; set; }
}
modelBuilder.Entity<Join>()
.HasOne(x => x.Parent)
.WithMany(x => x.Join)
.HasForeignKey(x => x.ParentId);
modelBuilder.Entity<Join>()
.HasOne(x => x.Child)
.WithMany(x => x.Join)
.HasForeignKey(x => x.ChildId);
但在您的情况下,您正试图将 Parent
和 Child
合并为同一类型。您仍然需要相同数量的外键和导航属性,但当然它们都需要是唯一的。
public class Document{
public int Id { get; set; }
public virtual ICollection<DocumentOffset> Parents { get; set; }
public virtual ICollection<DocumentOffset> Children { get; set; }
}
public class DocumentOffset{
public int ParentId { get; set; }
public int ChildId { get; set; }
public virtual Document Parent { get; set; }
public virtual Document Child { get; set; }
}
modelBuilder.Entity<DocumentOffset>()
.HasOne(x => x.Parent)
.WithMany(x => x.Children)
.HasForeignKey(x => x.ParentId);
modelBuilder.Entity<DocumentOffset>()
.HasOne(x => x.Child)
.WithMany(x => x.Parents)
.HasForeignKey(x => x.ChildId);
我的情况是我有一个包含发票的系统,我可以为每张发票创建收据。
这种关系是多对多的,因为我可以为每张发票生成几张收据,而且当我创建收据时,我可以将它与几张发票相关联。
我有以下两个类:代表发票或收据的Document
,以及文件之间关联的DocumentOffset
。
public class Document
{
public Document()
{
}
public int ID { get; set; }
public string Reference { get; set; }
[Required]
public int? DocumentKind { get; set; }
[Required]
public long DocumentNum { get; set; }
[Required]
public DateTime? CreateDate { get; set; }
[Required]
public int? EntityID { get; set; }
public double TaxDeduction { get; set; }
public int Amount { get; set; }
public double SumBeforeDiscount
{
get
{
return Document2List.Sum(x => x.Sum);
}
}
public double DiscountPercent { get; set; }
public double DiscountValue
{
get
{
return SumBeforeDiscount * DiscountPercent / 100;
}
}
public double SumBeforeTax
{
get
{
return SumBeforeDiscount - DiscountValue;
}
}
public int TaxPercent { get; set; } = 17;
public double TaxValue
{
get
{
return SumBeforeTax * TaxPercent / 100;
}
}
public double Sum
{
get
{
if(DocumentKind == (int)Enums.DocumentKind.eDocumentKind.Reciept || DocumentKind == (int)Enums.DocumentKind.eDocumentKind.SupplierReciept)
{
return Document3List.Sum(x => x.Sum).Value;
}
return SumBeforeTax + TaxValue;
}
}
public double Paid
{
get
{
return Document3List.Where(x => x.Sum.HasValue).Sum(x => x.Sum.Value);
}
}
public double Balance
{
get
{
return Sum - Paid;
}
}
[Required]
public string Details { get; set; }
[Required]
public DateTime? Expire { get; set; }
public string VehicleID { get; set; }
public List<Document2> Document2List { get; set; } = new List<Document2>(); // Document items
public List<Document3> Document3List { get; set; } = new List<Document3>(); // Document payments when invoice and receipt produced in the same document
public Entity Entity { get; set; }
public ICollection<DocumentOffset> DocumentOffsets { get; set; } //this property
}
和
public class DocumentOffset
{
public int DocumentID { get; set; } //FK
public Document Document { get; set; }
public int RelatedDocumentID { get; set; } //FK
public Document RelatedDocument { get; set; }
public double Sum { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MissionCardWorker>().HasKey(x => new { x.MissionCardId, x.WorkerId });
modelBuilder.Entity<MissionCardItems>().HasKey(x => new { x.MissionCardId, x.ItemId });
modelBuilder.Entity<MissionCardMission>().HasKey(x => new { x.MissionCardId, x.MissionId });
modelBuilder.Entity<DocumentOffset>()
.HasOne(x => x.Document)
.WithMany(x => x.DocumentOffsets)
.HasForeignKey(x => x.RelatedDocumentID);
modelBuilder.Entity<DocumentOffset>()
.HasOne(x => x.RelatedDocument)
.WithMany(x => x.DocumentOffsets)
.HasForeignKey(x => x.DocumentID);
}
当我尝试添加迁移时出现以下错误:
Cannot create a relationship between 'Document.DocumentOffsets' and 'DocumentOffset.RelatedDocument', because there already is a relationship between 'Document.DocumentOffsets' and 'DocumentOffset.Document'. Navigation properties can only participate in a single relationship.
我应该怎么做才能解决这个问题?
谢谢:)
通常,对于多对多连接,您会遵循这样的模式;
public class Parent{
public int Id { get; set; }
public virtual ICollection<Join> Join { get; set; }
}
public class Join{
public int ParentId { get; set; }
public int ChildId { get; set; }
public virtual Parent Parent { get; set; }
public virtual Child Child { get; set; }
}
public class Child{
public int Id { get; set; }
public virtual ICollection<Join> Join { get; set; }
}
modelBuilder.Entity<Join>()
.HasOne(x => x.Parent)
.WithMany(x => x.Join)
.HasForeignKey(x => x.ParentId);
modelBuilder.Entity<Join>()
.HasOne(x => x.Child)
.WithMany(x => x.Join)
.HasForeignKey(x => x.ChildId);
但在您的情况下,您正试图将 Parent
和 Child
合并为同一类型。您仍然需要相同数量的外键和导航属性,但当然它们都需要是唯一的。
public class Document{
public int Id { get; set; }
public virtual ICollection<DocumentOffset> Parents { get; set; }
public virtual ICollection<DocumentOffset> Children { get; set; }
}
public class DocumentOffset{
public int ParentId { get; set; }
public int ChildId { get; set; }
public virtual Document Parent { get; set; }
public virtual Document Child { get; set; }
}
modelBuilder.Entity<DocumentOffset>()
.HasOne(x => x.Parent)
.WithMany(x => x.Children)
.HasForeignKey(x => x.ParentId);
modelBuilder.Entity<DocumentOffset>()
.HasOne(x => x.Child)
.WithMany(x => x.Parents)
.HasForeignKey(x => x.ChildId);