简体   繁体   English

如何将多个实体映射到一个表?

[英]How to have multiple entities mapped against one table?

I'm trying to use two different entities against the same table. 我正在尝试对同一张表使用两个不同的实体。 The purpose of having two entities is to limit the amount of attributes in one of them, because on one of the edit forms it should only be possible to change a few of the attributes. 具有两个实体的目的是限制其中一个实体的数量,因为在一种编辑形式上,只能更改其中一些属性。

So in order to avoid having to have the non-editable attributes as hidden to preserve their values, I thought having a separate entity with just a portion of the attributes would be a good idea. 因此,为了避免不得不隐藏不可编辑的属性以保留其值,我认为拥有一个仅包含部分属性的单独实体将是一个好主意。

So I have one entity with all the attributes, and one with just some of the attributes. 因此,我有一个具有所有属性的实体,而一个只有一些属性。 The problem is that I get this exception: 问题是我得到了这个异常:

`The entity types 'ApplicationMapping' and 'ApplicationMappingFull' cannot share table 'ApplicationMapping' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them. 实体类型'ApplicationMapping'和'ApplicationMappingFull'无法共享表'ApplicationMapping',因为它们不在同一类型层次结构中,或者没有有效的一对一外键关系且它们之间具有匹配的主键。

The entity config classes look like this: 实体配置类如下所示:

class ApplicationMappingFullConfiguration : EntityTypeConfiguration<ApplicationMappingFull>  
{  
  public ApplicationMappingFullConfiguration()  
  {  
    ToTable("ApplicationMapping");  
    HasKey(p => p.Id);  
  }  
}  

class ApplicationMappingConfiguration : EntityTypeConfiguration<ApplicationMapping>  
{  
  public ApplicationMappingConfiguration()  
  {  
    ToTable("ApplicationMapping");  
    HasKey(p => p.Id);  
  }  
}

How can I achieve what I'm trying to do? 我如何才能实现自己的目标? Is there a better/simpler way of doing it? 有没有更好/更简单的方法呢?

Thanks! 谢谢!

I would recommend having a single entity mapped to the table, but create two 'view' entities that contain only those properties that the form requires. 我建议将一个实体映射到表,但是创建两个仅包含表单所需属性的“视图”实体。

These view entities could contain methods to map data entered back to the underlying entity. 这些视图实体可以包含将输入的数据映射回基础实体的方法。

It seems what you're looking for is TPH (Table Per Hierarchy). 似乎您正在寻找的是TPH(每个层次的表)。 This is an relational inheritance pattern where a class and all it's subclasses share the same table and is supported natively by Entity Framework. 这是一种关系继承模式,其中一个类及其所有子类共享同一张表,并由Entity Framework本地支持。 In fact, if all you do is have one entity inherit from another, Entity Framework deploys this pattern by default. 实际上,如果您要做的只是使一个实体继承自另一个实体,则默认情况下,Entity Framework会部署此模式。 You don't need to do anything special at all. 您根本不需要做任何特别的事情。

However, there's a condition: since the properties on the base class must be enough on their own to be able to successfully save the row to the database, all your subclass properties must be optional -- at least on a database level. 但是,有一个条件:由于基类的属性必须足够独立才能成功将行保存到数据库,因此所有子类属性都必须是可选的-至少在数据库级别。 You could always enforce one or more properties to be required through the frontend user interface. 您始终可以通过前端用户界面强制实施一个或多个必需的属性。

UPDATE 更新

Expanding on my comment below, if all you're looking to do is return a subset of data from the table, then you already have all the tools you need. 在下面扩展我的评论,如果您要做的只是从表中返回数据的子集,那么您已经拥有了所需的所有工具。 You don't need two separate entities, just one entity (in this case, your ApplicationMappingFull class) and then you can use LINQ to return only those columns you need. 您不需要两个单独的实体,只需一个实体(在本例中为ApplicationMappingFull类),然后可以使用LINQ仅返回所需的那些列。

db.ApplicationMappingFulls.Select(m => new ApplicationMappingViewModel
    {
        SomeProperty = m.SomeProperty,
        OtherProperty = m.OtherProperty
    });

Behind the scenes, EF will issue a query that will only select the SomeProperty and OtherProperty columns, because that's all that's needed. 在幕后,EF将发出一个查询,将只能选择SomePropertyOtherProperty列,因为这是一个的所需的全部。 Your view model would not be connected to EF at all; 您的视图模型根本不会连接到EF。 it's just a class to hold the data returned by EF. 这只是保存EF返回的数据的类。

Another alternative is to have one class derive from the other, and hide or otherwise neuter the fields you dont wish to allow edit. 另一种选择是让一个类从另一个类派生,并隐藏或以其他方式使您不希望编辑的字段中性。

As an example... 举个例子...

class Full {
  public string ValueA {get;set;}
}

class Limited : Full {
  public new string ValueA {get; private set;}
}

This is admittedly not the greatest solution, but another choice you can use. 诚然,这不是最大的解决方案,而是可以使用的另一种选择。

You question has the answer. 您的问题有答案。

 The entity types 'ApplicationMapping' and 'ApplicationMappingFull' cannot share table 'ApplicationMapping' 

When you map an entity type to the table, you are defining the schema for the table. 当您将实体类型映射到表时,您正在定义表的架构。 As you said, you have one entity with all the attributes, and one with just some of the attributes. 如您所说,您有一个具有所有属性的实体,而一个仅具有某些属性。 When you map an entity to the table, you need to map all the columns of the table. 将实体映射到表时,需要映射表的所有列。

So in one line, "It is not possible". 因此,在一行中,“不可能”。

To achieve the solution of your problem , you can do what Paddy suggested. 为了解决您的问题 ,您可以按照Paddy的建议进行。 Else you can create a base class with minimum required attributes then extend that class and add remaining attributes. 否则,您可以创建具有最少必需属性的基类,然后扩展该类并添加其余属性。 While passing the model to the view, pass the base class object. 将模型传递给视图时,传递基类对象。 However you can use extended class object while fetching the record from database. 但是,您可以在从数据库中获取记录时使用扩展类对象。

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

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