简体   繁体   English

实体框架使用中间表一对多映射,而没有该表的类

[英]Entity Framework map one to many with an intermediate table without a class for that table

I have 我有

Issue
{
    //Id, etc
    public List<CloudFile> Files { get; set; }
}

and since CloudFile can be used by other classes, the cleanest solution seems to create an intermediate table called IssueFile . 而且由于CloudFile可以被其他类使用,所以最干净的解决方案似乎是创建一个称为IssueFile的中间表。 The thing is I have no use for such a class in my code... so how do I map between Issue and CloudFile without creating such an intermediate class. 问题是我的代码中没有使用这样的类...所以如何在IssueCloudFile之间CloudFile而不创建这样的中间类。 Or is this even possible? 还是有可能吗? I know that there are similar questions ( One to Many mapping with an intermediate table ) but they create this intermediate but, hopefully, unnecessary class. 我知道也有类似的问题( 带有中间表的一对多映射 ),但是它们创建了这个中间但希望是不必要的类。

The only time there is no getting out of an intermediate table is for a many-to-many mapping. 唯一无法摆脱中间表的地方是多对多映射。 In your case, you're dealing with a many-to-optional or many-to-required. 就您而言,您要处理的是多对任意或多对多需求。 Now you have two options: 现在,您有两个选择:

1) Foreign Key association: for this you will need to define your foreign key in your CloudFile class. 1)外键关联:为此,您将需要在CloudFile类中定义外键。 This has some advantages, because you can update relationships by changing foreign key value and you can add new entities without needing the dependant entity by using dummy foreign key values. 这具有一些优点,因为您可以通过更改外键值来更新关系,并且可以通过使用虚拟外键值来添加新实体而无需依赖实体。 Overall it's just easier to work with. 总的来说,它更容易使用。

modelBuilder.Entity<Issue>()
  .HasMany(i => i.CloudFile)
  .WithRequired(i => i.Issue)
  .HasForeignKey(i => i.Id);

2) Independant association: no foreign key on your model (it does use the key internally of course) and the relationship has it's own state tracked. 2)独立关联:模型上没有外键(当然,它确实在内部使用键),并且关系具有自己的状态跟踪。

modelBuilder.Entity<Issue>()
  .HasMany(i => i.CloudFile)
  .WithRequired(i => i.Issue)
  .Map(i => i.MapKey("Id"));

What you want is Table-per-Type (TPT) inheritance. 您想要的是每类型表(TPT)继承。 CloudFile would be your base class and the derived types would represent the relationship to the owning entities ( Issue , Order , etc.): CloudFile是您的基类,派生类型将表示与拥有实体的关系( IssueOrder等):

[Table( "CloudFile" )]
public class CloudFile
{
    public int Id { get; set; }
}

[Table( "IssueCloudFile" )]
public class IssueCloudFile : CloudFile
{
}

public class Issue
{
    public int Id { get; set; }
    public List<IssueCloudFile> Files { get; set; }
}

Or via Fluent API: 或通过Fluent API:

modelBulider.Entity<CloudFile>().ToTable( "CloudFile" );
modelBuilder.Entity<IssueCloudFile>().ToTable( "IssueCloudFile" );

If you use DbSet<CloudFile> only without DbSet s for a derived type of CloudFile , use .OfType<T>() to get only those types: 如果使用DbSet<CloudFile>仅而不DbSet S表示派生类型的CloudFile ,使用.OfType<T>()只得到的那些类型:

var issueCloudFiles = db.CloudFiles.OfType<IssueCloudFile>();
// or through the referencing entities themselves
issueCloudFiles = db.Issues.SelectMany( i => i.Files );

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

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