EF实体继承

在使用EF时,发现实体之间有个继承的关系。所以想到是不是可以将一些通用的字段作为基类,例如每个实体都有版本号、创建者等字段。所以采用以下Modle first 方式实现。

首先创建Model

当然在创建Model的时候,需要注意只用基类才可以申明主键。

保存-由实体生成数据库

  1 -- --------------------------------------------------
  2 -- Entity Designer DDL Script for SQL Server 2005, 2008, 2012 and Azure
  3 -- --------------------------------------------------
  4 -- Date Created: 07/17/2018 12:11:28
  5 -- Generated from EDMX file: E:\Test\SimpleTest\SimpleTest.Entity\TestSystem.edmx
  6 -- --------------------------------------------------
  7  
  8 SET QUOTED_IDENTIFIER OFF;
  9 GO
 10 USE [TestSystem];
 11 GO
 12 IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
 13 GO
 14  
 15 -- --------------------------------------------------
 16 -- Dropping existing FOREIGN KEY constraints
 17 -- --------------------------------------------------
 18  
 19 IF OBJECT_ID(N'[dbo].[FK_Account_inherits_BaseEntity]', 'F') IS NOT NULL
 20     ALTER TABLE [dbo].[BaseEntity_Account] DROP CONSTRAINT [FK_Account_inherits_BaseEntity];
 21 GO
 22 IF OBJECT_ID(N'[dbo].[FK_Product_inherits_BaseEntity]', 'F') IS NOT NULL
 23     ALTER TABLE [dbo].[BaseEntity_Product] DROP CONSTRAINT [FK_Product_inherits_BaseEntity];
 24 GO
 25  
 26 -- --------------------------------------------------
 27 -- Dropping existing tables
 28 -- --------------------------------------------------
 29  
 30 IF OBJECT_ID(N'[dbo].[BaseEntity]', 'U') IS NOT NULL
 31     DROP TABLE [dbo].[BaseEntity];
 32 GO
 33 IF OBJECT_ID(N'[dbo].[BaseEntity_Account]', 'U') IS NOT NULL
 34     DROP TABLE [dbo].[BaseEntity_Account];
 35 GO
 36 IF OBJECT_ID(N'[dbo].[BaseEntity_Product]', 'U') IS NOT NULL
 37     DROP TABLE [dbo].[BaseEntity_Product];
 38 GO
 39  
 40 -- --------------------------------------------------
 41 -- Creating all tables
 42 -- --------------------------------------------------
 43  
 44 -- Creating table 'BaseEntity'
 45 CREATE TABLE [dbo].[BaseEntity] (
 46     [Id] int IDENTITY(1,1) NOT NULL,
 47     [CreateId] int  NOT NULL,
 48     [CreateTime] datetime  NOT NULL,
 49     [LastModifierId] int  NOT NULL,
 50     [LastModifyTime] datetime  NOT NULL,
 51     [Version] int  NOT NULL
 52 );
 53 GO
 54  
 55 -- Creating table 'BaseEntity_Account'
 56 CREATE TABLE [dbo].[BaseEntity_Account] (
 57     [Name] nvarchar(max)  NOT NULL,
 58     [AppKeyId] nvarchar(max)  NOT NULL,
 59     [AppSecretKey] nvarchar(max)  NOT NULL,
 60     [MarketPlaceId] nvarchar(max)  NOT NULL,
 61     [Id] int  NOT NULL
 62 );
 63 GO
 64  
 65 -- Creating table 'BaseEntity_Product'
 66 CREATE TABLE [dbo].[BaseEntity_Product] (
 67     [Code] nvarchar(max)  NOT NULL,
 68     [Title] nvarchar(max)  NOT NULL,
 69     [Description] nvarchar(max)  NOT NULL,
 70     [Price] decimal(18,0)  NOT NULL,
 71     [Weight] decimal(18,0)  NOT NULL,
 72     [Id] int  NOT NULL
 73 );
 74 GO
 75  
 76 -- --------------------------------------------------
 77 -- Creating all PRIMARY KEY constraints
 78 -- --------------------------------------------------
 79  
 80 -- Creating primary key on [Id] in table 'BaseEntity'
 81 ALTER TABLE [dbo].[BaseEntity]
 82 ADD CONSTRAINT [PK_BaseEntity]
 83     PRIMARY KEY CLUSTERED ([Id] ASC);
 84 GO
 85  
 86 -- Creating primary key on [Id] in table 'BaseEntity_Account'
 87 ALTER TABLE [dbo].[BaseEntity_Account]
 88 ADD CONSTRAINT [PK_BaseEntity_Account]
 89     PRIMARY KEY CLUSTERED ([Id] ASC);
 90 GO
 91  
 92 -- Creating primary key on [Id] in table 'BaseEntity_Product'
 93 ALTER TABLE [dbo].[BaseEntity_Product]
 94 ADD CONSTRAINT [PK_BaseEntity_Product]
 95     PRIMARY KEY CLUSTERED ([Id] ASC);
 96 GO
 97  
 98 -- --------------------------------------------------
 99 -- Creating all FOREIGN KEY constraints
100 -- --------------------------------------------------
101  
102 -- Creating foreign key on [Id] in table 'BaseEntity_Account'
103 ALTER TABLE [dbo].[BaseEntity_Account]
104 ADD CONSTRAINT [FK_Account_inherits_BaseEntity]
105     FOREIGN KEY ([Id])
106     REFERENCES [dbo].[BaseEntity]
107         ([Id])
108     ON DELETE CASCADE ON UPDATE NO ACTION;
109 GO
110  
111 -- Creating foreign key on [Id] in table 'BaseEntity_Product'
112 ALTER TABLE [dbo].[BaseEntity_Product]
113 ADD CONSTRAINT [FK_Product_inherits_BaseEntity]
114     FOREIGN KEY ([Id])
115     REFERENCES [dbo].[BaseEntity]
116         ([Id])
117     ON DELETE CASCADE ON UPDATE NO ACTION;
118 GO
119  
120 -- --------------------------------------------------
121 -- Script has ended
122 -- --------------------------------------------------
123  
View Code

其次根据数据库生成表

根据数据库脚本,就可以知道最终建立了3张表。

最后,程序中调用,并监视执行的Sql

1、新增

程序调用

 1               Account a = new Account()
 2                 {
 3                     Name = "US-1",
 4                     AppKeyId = "xxxxxxddsdfes",
 5                     AppSecretKey = "exdfesdKey",
 6                     MarketPlaceId = "jkhyed",
 7                     LastModifierId = 1,
 8                     LastModifyTime = DateTime.Now,
 9                     Version = 0,
10                     CreateId = '1',
11                     CreateTime = DateTime.Now,
12  
13                 };
14                 using (TestSystemContainer context = new TestSystemContainer())
15                 {
16                     context.BaseEntity.Add(a);
17                     context.SaveChanges();
18                 }
19  
View Code

执行的Sql:

 1 INSERT [dbo].[BaseEntity]([CreateId], [CreateTime], [LastModifierId], [LastModifyTime], [Version])
 2 VALUES (@0, @1, @2, @3, @4)
 3 SELECT [Id]
 4 FROM [dbo].[BaseEntity]
 5 WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()
 6  
 7  
 8 -- @0: '49' (Type = Int32)
 9  
10 -- @1: '2018/7/17 星期二 14:46:28' (Type = DateTime2)
11  
12 -- @2: '1' (Type = Int32)
13  
14 -- @3: '2018/7/17 星期二 14:46:28' (Type = DateTime2)
15  
16 -- @4: '0' (Type = Int32)
17  
18 -- Executing at 2018/7/17 星期二 14:46:29 +08:00
19  
20 INSERT [dbo].[BaseEntity_Account]([Name], [AppKeyId], [AppSecretKey], [MarketPlaceId], [Id])
21 VALUES (@0, @1, @2, @3, @4)
22  
23 -- @0: 'US-1' (Type = String, Size = -1)
24  
25 -- @1: 'xxxxxxddsdfes' (Type = String, Size = -1)
26  
27 -- @2: 'exdfesdKey' (Type = String, Size = -1)
28  
29 -- @3: 'jkhyed' (Type = String, Size = -1)
30  
31 -- @4: '3' (Type = Int32)
View Code

2、查询

程序调用

 1                 using (TestSystemContainer searchContext = new TestSystemContainer())
 2                 {
 3                     var query = searchContext.BaseEntity.AsNoTracking();
 4                     System.Diagnostics.Debug.WriteLine(query.ToString());
 5                     List <BaseEntity> baseEnList= query.ToList();
 6                     if (baseEnList != null)
 7                     {
 8                         foreach (var item in baseEnList)
 9                         {
10                             Product product = item as Product;
11                             if (product != null)
12                             {
13                               System.Diagnostics.Debug.Print("这是产品:"+product.Title);
14                             }
15                            
16                             else
17                             {
18                                 Account account = item as Account;
19                                 if (account != null)
20                                 {
21                                     System.Diagnostics.Debug.Print("这是账号信息:"+ account.Name);
22                                 }
23                                 else
24                                 {
25                                     System.Diagnostics.Debug.Print("测试失败,查到的数据不是产品");
26                                 }
27                             }
28                         }
29                     
30                     }
31                     else {
32                         System.Diagnostics.Debug.Print("无数据");
33                     }
34                 }
35  
View Code

执行的Sql

 1 SELECT
 2     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN '0X' WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN '0X0X' ELSE '0X1X' END AS [C1],
 3     [Extent1].[Id] AS [Id],
 4     [Extent1].[CreateId] AS [CreateId],
 5     [Extent1].[CreateTime] AS [CreateTime],
 6     [Extent1].[LastModifierId] AS [LastModifierId],
 7     [Extent1].[LastModifyTime] AS [LastModifyTime],
 8     [Extent1].[Version] AS [Version],
 9     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS varchar(1)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN [Project2].[Name] END AS [C2],
10     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS varchar(1)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN [Project2].[AppKeyId] END AS [C3],
11     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS varchar(1)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN [Project2].[AppSecretKey] END AS [C4],
12     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS varchar(1)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN [Project2].[MarketPlaceId] END AS [C5],
13     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS varchar(1)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN CAST(NULL AS varchar(1)) ELSE [Project1].[Code] END AS [C6],
14     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS varchar(1)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN CAST(NULL AS varchar(1)) ELSE [Project1].[Title] END AS [C7],
15     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS varchar(1)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN CAST(NULL AS varchar(1)) ELSE [Project1].[Description] END AS [C8],
16     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS decimal(18,0)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN CAST(NULL AS decimal(18,0)) ELSE [Project1].[Price] END AS [C9],
17     CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS decimal(18,0)) WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN CAST(NULL AS decimal(18,0)) ELSE [Project1].[Weight] END AS [C10]
18     FROM   [dbo].[BaseEntity] AS [Extent1]
19     LEFT OUTER JOIN  (SELECT
20         [Extent2].[Code] AS [Code],
21         [Extent2].[Title] AS [Title],
22         [Extent2].[Description] AS [Description],
23         [Extent2].[Price] AS [Price],
24         [Extent2].[Weight] AS [Weight],
25         [Extent2].[Id] AS [Id],
26         cast(1 as bit) AS [C1]
27         FROM [dbo].[BaseEntity_Product] AS [Extent2] ) AS [Project1] ON [Extent1].[Id] = [Project1].[Id]
28     LEFT OUTER JOIN  (SELECT
29         [Extent3].[Name] AS [Name],
30         [Extent3].[AppKeyId] AS [AppKeyId],
31         [Extent3].[AppSecretKey] AS [AppSecretKey],
32         [Extent3].[MarketPlaceId] AS [MarketPlaceId],
33         [Extent3].[Id] AS [Id],
34         cast(1 as bit) AS [C1]
35         FROM [dbo].[BaseEntity_Account] AS [Extent3] ) AS [Project2] ON [Extent1].[Id] = [Project2].[Id]
36  
37  
38  
39  
View Code

总结

1、在新增或修改数据时需要操作两个表;

2、在查询时EF进行了多表的级联操作,并且在程序中需要进行转换,才能将父类型转换成实际的子类型。

所以不建议使用EF的继承方式建立实体间关系。

猜你喜欢

转载自www.cnblogs.com/johnyong/p/9357507.html
今日推荐