【问题标题】:How to create multiple table references to one table - Entity framework如何为一张表创建多个表引用 - 实体框架
【发布时间】:2019-03-27 17:47:32
【问题描述】:

我们要求一个表中需要引用多个表,如图所示。

请注意,该图不是正确的数据库模型,而只是代表了我们的要求。您能建议在SQL Server DB 和Entity Framework 6 中实现上述的正确方法吗?

示例:一个销售订单(在 SalesOrder 表中)可以有多个文件,这些上传的文件详细信息将存储在 UploadedFile 表中。 OrderTable 和 Invoice 也是如此。

因此,我们需要在 FileUpload 表与其他相关表之间建立具有 FK 关系的适当 DB 模型。

注意:所有的表 PK 都是自增的 int 值,我们将来可能需要添加更多的实体(表)

【问题讨论】:

  • 你打算使用 Code First 吗?
  • 你可以将3个表的3个id保存在一个表中,然后在新表和上传的文件之间建立关系
  • Foreign Key to multiple tables 的可能重复项。认为这很好地反映了您的问题,所以我将删除我的帖子,因为它在链接的帖子中有更详细的介绍。
  • @Tishan,我已经写了一个使用EF Code First的示例,如果你使用C#并且你想有一个替代方案,请添加C#标签并在这里回复我,我会添加样本作为答案。谢谢。
  • 感谢@Tanner 的链接,我检查了那里的答案,似乎第四个选项更好,但该解决方案使实体表有一个列,仅用于它的类型,并且对于每条记录始终相同那个特定的表,例如,我的 SalesOrder 表应该有一个像“UploadTypeId”这样的列,它的值总是相同的(即 1),所以在考虑良好的数据库设计时问这样可以吗?

标签: c# asp.net sql-server database entity-framework-6


【解决方案1】:

为了为您提供替代方案,正如您所说,您使用的是实体框架,这里是在 C# 上完成的 Code First 实现示例。您可以在 Visual Studio 中通过包管理器控制台迁移来创建和更新架构。我已经使用 Fluent API 来定义关系,因为这是推荐的替代方法。

public class SampleContext : DbContext
{
    public SampleContext()
        : base("name=YourConnection")
    {
    }

    public DbSet<SalesOrder> SalesOrders { get; set; }
    public DbSet<CreditOrder> CreditOrders { get; set; }
    public DbSet<Invoice> Invoices { get; set; }
    public DbSet<UploadedFile> UploadedFiles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SalesOrder>()
            .HasKey(so => so.Id);

        modelBuilder.Entity<CreditOrder>()
            .HasKey(co => co.Id);

        modelBuilder.Entity<Invoice>()
            .HasKey(i => i.Id);

        modelBuilder.Entity<UploadedFile>()
            .HasKey(u => u.Id);

        modelBuilder.Entity<UploadedFile>()
            .HasRequired(u => u.SalesOrder)
            .WithMany(s => s.UploadedFiles)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<UploadedFile>()
            .HasRequired(u => u.CreditOrder)
            .WithMany(c => c.UploadedFiles)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<UploadedFile>()
            .HasRequired(u => u.Invoice)
            .WithMany(c => c.UploadedFiles)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<UploadedFile>()
            .Property(uf => uf.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<SalesOrder>()
            .Property(so => so.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<CreditOrder>()
            .Property(co => co.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<Invoice>()
            .Property(i => i.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        base.OnModelCreating(modelBuilder);
    }
}

// Collections of navigation properties should be included in classes for a one-to-many relationship

public class SalesOrder
{
    public int Id { get; set; }
    public string MyColumn { get; set; }
    public IList<UploadedFile> UploadedFiles { get; set; }
}

public class CreditOrder
{
    public int Id { get; set; }
    public string MyColumn { get; set; }
    public IList<UploadedFile> UploadedFiles { get; set; }
}

public class Invoice
{
    public int Id { get; set; }
    public string MyColumn { get; set; }
    public IList<UploadedFile> UploadedFiles { get; set; }
}

public class UploadedFile
{
    public int Id { get; set; }
    public SalesOrder SalesOrder { get; set; }
    public CreditOrder CreditOrder { get; set; }
    public Invoice Invoice { get; set; }
    public string FilePath { get; set; }
    public string FileType { get; set; }
}

public class SalesOrder
{
    public int Id { get; set; }
    public string MyColumn { get; set; }
    public IList<UploadedFile> UploadedFiles { get; set; }
}

public class CreditOrder
{
    public int Id { get; set; }
    public string MyColumn { get; set; }
    public IList<UploadedFile> UploadedFiles { get; set; }
}

public class Invoice
{
    public int Id { get; set; }
    public string MyColumn { get; set; }
    public IList<UploadedFile> UploadedFiles { get; set; }
}

public class UploadedFile
{
    public int Id { get; set; }
    public SalesOrder SalesOrder { get; set; }
    public CreditOrder CreditOrder { get; set; }
    public Invoice Invoice { get; set; }
    public string FilePath { get; set; }
    public string FileType { get; set; }
}

【讨论】:

    【解决方案2】:

    在阅读我的回答之前,请注意以下信息:

    可以在Foreign Key to multiple tables 上的这篇文章中找到更好的答案。


    我的回答:

    请参阅 here 以获取来自 MDSN 页面的创建表文档的更多信息。

    我所采用的设计为那里的每个表提供了自己的 id 作为主键。然后我使用 UploadedFile 表以 外键 的形式添加对每个表的引用。

    我创建了一些可以帮助您创建这些表的虚拟脚本。请让我知道这可不可以帮你。谢谢!

    SQL 脚本:

    SalesOrder 表:

    Create Table dbo.SalesOrder(
    SalesOrderID int not null, identity primary key,
    --enter whatever other columsn you have here
    )
    

    CreditOrder 表:

    Create Table sbo.CreditOrder(
    CreditOrderID int not null, identity primary key,
    --enter whatever other columsn you have here
    )
    

    发票表:

    Create Table dbo.Invoice(
    InvoiceID int not null, identity primary key,
    --enter whatever other column you have here
    )
    

    上传的文件表:

    Create table dbo.UploadedFile(
    UploadFileID int not null identity primary key,
    SalesOrderID int null Foreign Key References SalesOrder(SalesOrderID),
    CreditOrderID int null Foreign Key References CreditOrder(CreditOrderID),
    InvoiceID int null Foreign Key References CreditOrder(InvoiceID),
    --enter whatever other columns you have here
    )
    

    【讨论】:

    • 从堆栈溢出用户中删除它更好吗?还是真的很重要? @Tanner
    • 我刚刚所做的更改怎么样? @Tanner
    • 感谢您的回复,我们考虑过这种方式,但问题如问题中所述,将来可能会添加更多表格,这些表格也需要上传文件。因此,在这种情况下,我们需要修改 UploadedFile 表以添加新的参考列。我们不确定这是否是实现我们目标的正确方法。
    • 它们的结构化方式允许您在从这些基表继续前进时添加更多参考列,但是好的,感谢您将其视为解决方案。 @TishanMadhawa
    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2014-03-17
    • 2021-11-04
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多