什么是实体框架中的复杂类型以及何时使用它?

时间:2016-06-14 07:56:24

标签: c# asp.net entity-framework

我试图在复杂类型上阅读msdn article。但它没有解释何时使用它。关于复杂类型以及何时使用它们的网络也没有全面的解释。

2 个答案:

答案 0 :(得分:38)

冗长的解释是在你链接的MSDN文章中...所以你基本上想要一个简单的解释:

复杂类型是一组属性,它们存在于C#的自己的对象中,但是映射到现有表(包含它的实体的表)上的列,而不是拥有自己的表(这将是需要钥匙等。)。

所以想象一下你想在数据库上使用这个表:

Select Types (1,3,9)
Select ANum (0,5)
Type 1, Num 5 should be bigger than 10 In Val2
Type 1, Num 5, should be smaller than 30 In Val2
Type 3, Num 0, should be smaller than 8 In Val1

但是想在C#实体中使用这个结构:

SELECT analyse.* FROM analyse 
INNER JOIN 
(SELECT ID FROM analyse WHERE Type = 1 AND Num = 5 AND Val2 < 30 AND Val2 > 10) AS a1 ON a1.SID = analyse.SID 
(SELECT SID FROM analyse WHERE Type = 3 AND Num = 0 AND Val1 > 8) AS a3 ON a2.SID = analyse.SID 
WHERE Type IN (1,3,9) AND Num IN (0,5) ORDER BY ID, Type, Order, Num ASC

因此Orders ---------- Id (bigint) Name (varchar) Street (varchar) Region (varchar) Country (varchar) 将是一个复杂的类型:它本身不存在(在数据库中不会有class Order { long Id; string Name; struct Address { string Street; string Region; string Country; } } 表)...它只会作为一组存在Address表上的列。

正如@HenkHolterman在评论中所指出的,具有复杂类型的价值是拥有一个C#实体,可以将其用作其他包含实体的值(在我的示例中,您可以使用Addresses例如,Orders实体,但它将被映射为Address表中的一组列。它使得处理复杂类型中的值变得容易。

缺点恰恰在于:如果发生在不同实体之间可以共享相同的Supplier(或您使用的任何其他类型),则可能必须在数据库中多次重复复杂类型值。

您选择使用复杂类型还是单独的实体取决于您和您的设计。

答案 1 :(得分:8)

考虑这个ContactDetails类,例如:

public class ContactDetails
{
    public string HomePhone { get; set; }
    public string MobilePhone { get; set; }
    public string FaxNumber { get; set; }
}

默认情况下,EF会将ContactDetails视为实体。这意味着如果(例如)您拥有导航属性为Person类型的ContactDetails类,则EF会将Person.ContactDetails关系映射到其他表(因为实体具有自己的身份,因此其他实体可能会引用它 - 而这需要关系术语中的不同表格。)

通过将ContactDetails表示为复杂类型,EF将不再将其视为需要关系的实体,而是将其映射到父级的同一个表(包含)实体(我的示例中为Person),有效地使其成为Value Object