简体   繁体   English

EF代码优先1:相同模型之间的1:* 1:0..1关系

[英]EF code-first 1:* 1:0..1 relationship between the same models

I have two models 我有两个模型

public class A{
    public AID { get; set; }

    public int? MainBID { get; set; }
    [ForeignKey("MainBID")]
    public B MainB { get; set; }
}
public class B{
    public int BID { get; set; }

    public int? AID { get; set; }
    [ForeignKey("AID")]
    public virtual A Owner { get; set;}
}

The relationship I want to model is A has many B. A may also have a specially designated B (main B). 我要建模的关系是A有很多B。A也可能有一个专门指定的B(主B)。

However the way I have it set up it has a hard time identifying the principal and using fluent: 但是,我的设置方式很难确定主体并使用流利的语言:

modelBuilder
    .Entity<A>()
    .HasOptional(x => x.MainB)
    .WithOptionalDependent();

It gives me Multiplicity is not valid in Role 'A_MainB_Source' in relationship 'A_MainB'. 它给我多重性在关系“ A_MainB”中的角色“ A_MainB_Source”中无效。 Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'. 因为从属角色属性不是关键属性,所以从属角色多重性的上限必须为'*'。

I think my trouble is trying to describe to EF that these are two separate relationships and not the same relationship described front-and-back. 我认为我的麻烦是试图向EF描述这是两个独立的关系,而不是前后描述的相同关系。 Can anyone guide me in this? 有人可以在这方面指导我吗?

EDIT: Adds an real life example 编辑:添加一个真实的例子

I have need to model a series of teaching courses (each is called a "Module"). 我需要对一系列的教学课程进行建模(每个课程都称为“模块”)。 All "Modules" represent a webpage conveying the information for that particular course. 所有“模块”都代表一个传达该特定课程信息的网页。 Each Module can have many "Resource"s (downloadable binary files). 每个模块可以具有许多“资源”(可下载的二进制文件)。

Some modules can have a Resource that represents the same information as the webpage. 某些模块可以具有表示与网页相同的信息的资源。 As in some modules can have a Resource that can be printed out and consumed instead of sitting in front of your machine reading through the webpage. 与在某些模块中一样,可以将资源打印出来并消耗掉,而不必坐在机器前浏览网页。 A PDF version of the webpage. 网页的PDF版本。

So in the above each module has many resources. 因此,在上面的每个模块中都有许多资源。 But each module can optionally have a "special" resource that needs to be called out separately as well as wherever other resources are used. 但是,每个模块可以选择具有“特殊”资源,无论使用什么其他资源,都需要分别调用它。

I considered just having a flag on Resource to indicate that a resource is special in some way but that will allow for 0..* which is not what I want. 我考虑过在Resource上放一个标志,以某种方式表明资源是特殊的,但这将允许0 .. *,这不是我想要的。 I thought this might be cleaner. 我认为这可能更干净。 But I have so far not been able to get this to work with EF. 但是到目前为止,我还无法使它与EF一起使用。

this is a working example: 这是一个工作示例:

public class Module
    {
       public int Id { get; set; }
       public string Name { get; set; }
       public ICollection<Resource> Resources { get; set; }
       public int? SpecialResourceId { get; set; }
       public Resource SpecialResource { get; set; }
    }

    public class Resource
    {
        public int Id { get; set; }
        public int? ModuleId { get; set; }
        public Module Module { get; set; }
        public virtual Module IsSpecialForModule { get; set; }
    }

    public class MyContext : DbContext
    {
        public virtual DbSet<Module> Modules { get; set; }
        public virtual DbSet<Resource> Resources { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
           modelBuilder.Entity<Module>()
                .HasMany(x=>x.Resources)
                .WithOptional(x=>x.Module)
                .HasForeignKey(x=>x.ModuleId)
                .WillCascadeOnDelete(false);

            modelBuilder.Entity<Resource>()
                .HasOptional(x=>x.IsSpecialForModule)
                .WithOptionalDependent(x=>x.SpecialResource)
                .WillCascadeOnDelete(false);
        }
    }

if your special resource, can be special for many modules then your model is changing like this: 如果您的特殊资源对于许多模块而言可能是特殊的,那么您的模型就会像这样变化:

 public class Resource
    {
        public int Id { get; set; }
        public int? ModuleId { get; set; }
        public Module Module { get; set; }
        public virtual ICollection<Module> IsSpecialForModules { get; set; }
    }

and the config. 和配置。 will be : 将会 :

   modelBuilder.Entity<Resources>()
                .HasMany(x=>x.IsSpecialForModules )
                .WithOptional(x=>x.SpecialResource )
                .HasForeignKey(x=>x.SpecialResourceId )
                .WillCascadeOnDelete(false);

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

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