简体   繁体   English

在代码中为实体框架定义关系 Model(未规范化)

[英]Define Relationship in Code for Entity Framework Model (not normalizied)

I am trying to force a relationship in code where it does not exist in the database.我试图在数据库中不存在的代码中强制建立关系。 I don't have the option to redefine the database.我没有重新定义数据库的选项。 Below are the classes generated by EF.以下是 EF 生成的类。

For each survey, there are one or form elements.对于每个调查,都有一个或表单元素。 That is defined in the database and comes through in the classes.这是在数据库中定义的,并在类中出现。 For each form element, there are zero, one, or more sub elements with each type being specific to it's own table.对于每个表单元素,有零个、一个或多个子元素,每种类型都特定于它自己的表。 For example, if the ElementType is 'header' than the look up needs to hit the SurveyFormHeaderElement table where the SurveyFormHeaderElement.SurveyFormHeaderElementID is equal to SurveyFormElement.ElementID.例如,如果 ElementType 是“header”,则查找需要命中 SurveyFormHeaderElement.SurveyFormHeaderElementID 等于 SurveyFormElement.ElementID 的 SurveyFormHeaderElement 表。 There are other tables as well for prompts and lookups with the SurveyFormElement.ElementType indicating which table to do the lookup in.还有其他表用于提示和查找,其中 SurveyFormElement.ElementType 指示要在哪个表中进行查找。

I'd like to define this in the partial classes I am using for metadata so they don't get overwritten when the model updates.我想在我用于元数据的部分类中定义它,这样当 model 更新时它们就不会被覆盖。

// generated code
namespace Surveys.EF.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Survey
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Survey()
        {
            this.SurveyFormElements = new HashSet<SurveyFormElement>();
        }
    
        public int SurveyID { get; set; }
        public string SurveyTitle { get; set; }
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<SurveyFormElement> SurveyFormElements { get; set; }
    }
}

// generated code
namespace Surveys.EF.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class SurveyFormElement
    {
        public int SurveyFormElementID { get; set; }
        public int SurveyID { get; set; }
        public string ElementType { get; set; }
        public int ElementID { get; set; }
        public int ElementOrder { get; set; }
    
        public virtual Survey Survey { get; set; }
    }
}

//generated code
namespace Surveys.EF.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class SurveyFormHeaderElement
    {
        public int SurveyFormHeaderElementID { get; set; }
        public string HeaderType { get; set; }
        public string HeaderText { get; set; }
    }
}

// meta
namespace Surveys.EF.Models
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    [MetadataType(typeof(SurveyFormElementMetaData))]
    public partial class SurveyFormElement
    {
        private ICollection<SurveyFormHeaderElement> _HeaderElements;
        public virtual ICollection<SurveyFormHeaderElement> HeaderElements
        {
            get { return _HeaderElements;  }
            set { _HeaderElements = ?; } //assuming this would pull from SurveyFormHeaderElement dbcontext where SurveyFormHeaderElementID equals this.ElementID
        }
    }

    public class SurveyFormElementMetaData
    {
        
    }
}

You would have to build an aggregate table:您将必须构建一个聚合表:

So lets say you have:所以假设你有:

Survey PK: 1 Name "Survey 1".调查 PK:1 名称“调查 1”。

And

SurveyHeaderType Pk: 1 Name: "Header" SurveyHeaderType Pk:1 名称:“标题”

SurveryFooterType Pk: 1 Name "Footer" SurveryFooterType Pk: 1 名称“页脚”

Survery_Type_Aggregate PK: 1 SurveyFooterTypeId: 1 SurveryHeaderTypeId: null Survery_Type_Aggregate PK:1 SurveyFooterTypeId:1 SurveryHeaderTypeId:null

But this is only required IF you can have multiple Types on 1 survey, if you can ONLY have one type on a survey, you need to create a relationship to EACH type, and just have all but 1 be null.但这仅在 1 个调查中可以有多个类型时才需要,如果调查中只能有一个类型,则需要创建与每个类型的关系,并且除了 1 之外的所有类型都是 null。

So becomes于是就变成了

Survey PK: 1 SurveyTypeHeaderId: 1 SurveyTypeFooterId: null调查 PK:1 SurveyTypeHeaderId:1 SurveyTypeFooterId:null

Survey PK: 2 SurveyTypeHeaderId: null SurveyTypeFooterId: 1调查 PK:2 SurveyTypeHeaderId:null SurveyTypeFooterId:1

But a relationship can only be created between two tables.但是只能在两个表之间创建关系。 By linking two values on said table.通过链接所述表上的两个值。

I am not aware that it is possible to create a relationship between multiple tables where it can "option" out which table you are referencing.我不知道可以在多个表之间创建关系,它可以“选择”您正在引用的表。 A relationship is always a contract between two tables.关系始终是两个表之间的契约。

The relationship between survey and header cannot, for example, reference footer, also. survey 和 header 之间的关系也不能,例如,引用页脚。

You can create a relationship between footer and survey, but it would have to be on an independent value pair.您可以在页脚和调查之间创建关系,但它必须位于独立的值对上。

You can make a relationship value optional, but allowing the FK value to be null. Then that just means you have no matching row of that type.您可以将关系值设置为可选,但允许 FK 值为 null。这就意味着您没有该类型的匹配行。 And then you have to check all references if they are not null, to find the type.然后你必须检查所有引用,如果它们不是 null,找到类型。

But it depends if you can have multiple types on a survey.但这取决于您是否可以在调查中使用多种类型。

As far as I know, what you want to do cannot be done, because a "relationship" is limited to two tables at all times.据我所知,你想做的事是做不到的,因为一个“关系”在任何时候都仅限于两个表。

You can of course have multiple relationships between many, many tables.您当然可以在很多很多表之间建立多种关系。 But a relationship, can only be between two tables, again, as far as I know.但是据我所知,关系只能在两个表之间。

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

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