`
chungle
  • 浏览: 59039 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

LINQ to SQL语句(25)之继承

阅读更多

继承支持

LINQ to SQL 支持单表映射,其整个继承层次结构存储在单个数据库表中。该表包含整个层次结构的所有可能数据列的平展联合。(联合是将两个表组合成一个表的结果,组合后的表包含任一原始表中存在的行。)每行中不适用于该行所表示的实例类型的列为 null。
单表映射策略是最简单的继承表示形式,为许多不同类别的查询提供了良好的性能特征,如果我们要在 LINQ to SQL 中实现这种映射,必须在继承层次结构的根类中指定属性 (Attribute) 和属性 (Attribute) 的属性 (Property)。我们还可以使用O/R设计器来映射继承层次结构,它自动生成了代码。

下面为了演示下面的几个例子,我们在O/R设计器内设计如下图所示的类及其继承关系。

继承

我们学习的时候还是看看其生成的代码吧!

具体设置映射继承层次结构有如下几步:

  1. 根类添加TableAttribute属性。
  2. 为层次结构中的每个类添加InheritanceMappingAttribute属性,同样是添加到根类中。每个 InheritanceMappingAttribute属性,定义一个Code属性和一个Type属性。Code属性的值显示在数据库表的IsDiscriminator列中,用来指示该行数据所属的类或子类。Type属性值指定键值所表示的类或子类。
  3. 仅在其中一个InheritanceMappingAttribute属性上,添加一个IsDefault属性用来在数据库表中的鉴别器值在继承映射中不与任何Code值匹配时指定回退映射。
  4. 为ColumnAttribute属性添加一个IsDiscriminator属性来表示这是保存Code值的列。

下面是这张图生成的代码的框架(由于生成的代码太多,我删除了很多“枝叶”,仅仅保留了主要的框架用于指出其实质的东西):

[Table(Name = "dbo.Contacts")]
[InheritanceMapping(Code = "Unknown", Type = typeof(Contact),
                    IsDefault = true)]
[InheritanceMapping(Code = "Employee", Type = typeof(EmployeeContact))]
[InheritanceMapping(Code = "Supplier", Type = typeof(SupplierContact))]
[InheritanceMapping(Code = "Customer", Type = typeof(CustomerContact))]
[InheritanceMapping(Code = "Shipper", Type = typeof(ShipperContact))]
public partial class Contact :
INotifyPropertyChanging, INotifyPropertyChanged
{
    [Column(Storage = "_ContactID",IsPrimaryKey = true, 
    IsDbGenerated = true)]
    public int ContactID{ }
    [Column(Storage = "_ContactType",IsDiscriminator = true)]
    public string ContactType{ }
}
public abstract partial class FullContact : Contact{ }
public partial class EmployeeContact : FullContact{ }
public partial class SupplierContact : FullContact{ }
public partial class CustomerContact : FullContact{ }
public partial class ShipperContact : Contact{ }

1.一般形式

日常我们经常写的形式,对单表查询。

var cons = from c in db.Contacts                       
           select c;
foreach (var con in cons) {
    Console.WriteLine("Company name: {0}", con.CompanyName);
    Console.WriteLine("Phone: {0}", con.Phone);
    Console.WriteLine("This is a {0}", con.GetType());
}

2.OfType形式

这里我仅仅让其返回顾客的联系方式。

var cons = from c in db.Contacts.OfType<CustomerContact>()
           select c;

初步学习,我们还是看看生成的SQL语句,这样容易理解。在SQL语句中查询了ContactType为Customer的联系方式。

SELECT [t0].[ContactType], [t0].[ContactName], [t0].[ContactTitle],
[t0].[Address],[t0].[City], [t0].[Region], [t0].[PostalCode], 
[t0].[Country], [t0].[Fax],[t0].[ContactID], [t0].[CompanyName], 
[t0].[Phone] FROM [dbo].[Contacts] AS [t0]
WHERE ([t0].[ContactType] = @p0) AND ([t0].[ContactType] IS NOT NULL)
-- @p0: Input NVarChar (Size = 8; Prec = 0; Scale = 0) [Customer]

3.IS形式

这个例子查找一下发货人的联系方式。

var cons = from c in db.Contacts
           where c is ShipperContact
           select c;

生成的SQL语句如下:查询了ContactType为Shipper的联系方式。大致一看好像很上面的一样,其实这里查询出来的列多了很多。实际上是Contacts表的全部字段。

SELECT [t0].[ContactType], [t0].[ContactID], [t0].[CompanyName],
[t0].[Phone],[t0].[HomePage], [t0].[ContactName],
[t0].[ContactTitle], [t0].[Address], [t0].[City],
[t0].[Region], [t0].[PostalCode], [t0].[Country],
[t0].[Fax],[t0].[PhotoPath], [t0].[Photo], [t0].[Extension]
FROM [dbo].[Contacts] AS [t0] WHERE ([t0].[ContactType] = @p0)
AND ([t0].[ContactType] IS NOT NULL)
-- @p0: Input NVarChar (Size = 7; Prec = 0; Scale = 0) [Shipper]

4.AS形式

这个例子就通吃了,全部查找了一番。

var cons = from c in db.Contacts
           select c as FullContact;

生成SQL语句如下:查询整个Contacts表。

SELECT [t0].[ContactType], [t0].[HomePage], [t0].[ContactName],
[t0].[ContactTitle],[t0].[Address], [t0].[City],
[t0].[Region], [t0].[PostalCode], [t0].[Country], 
[t0].[Fax], [t0].[ContactID], [t0].[CompanyName], 
[t0].[Phone], [t0].[PhotoPath],[t0].[Photo], [t0].[Extension]
 FROM [dbo].[Contacts] AS [t0]

5.Cast形式

使用Case形式查找出在伦敦的顾客的联系方式。

var cons = from c in db.Contacts
           where c.ContactType == "Customer" && 
                     ((CustomerContact)c).City == "London"
           select c;

生成SQL语句如下,自己可以看懂了。

SELECT [t0].[ContactType], [t0].[ContactID], [t0].[CompanyName],
[t0].[Phone], [t0].[HomePage],[t0].[ContactName],
[t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region],
[t0].[PostalCode], [t0].[Country], [t0].[Fax], [t0].[PhotoPath],
[t0].[Photo], [t0].[Extension]FROM [dbo].[Contacts] AS [t0]
WHERE ([t0].[ContactType] = @p0) AND ([t0].[City] = @p1)
-- @p0: Input NVarChar (Size = 8; Prec = 0; Scale = 0) [Customer]
-- @p1: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London]

6.UseAsDefault形式

当插入一条记录时,使用默认的映射关系了,但是在查询时,使用继承的关系了。具体看看生成的SQL语句就直截了当了。

//插入一条数据默认使用正常的映射关系
Contact contact = new Contact()
{
    ContactType = null,
    CompanyName = "Unknown Company",
    Phone = "333-444-5555"
};
db.Contacts.InsertOnSubmit(contact);
db.SubmitChanges();
//查询一条数据默认使用继承映射关系
var con =
    (from c in db.Contacts
     where c.CompanyName == "Unknown Company" &&
                            c.Phone == "333-444-5555"
     select c).First();

生成SQL语句如下:

INSERT INTO [dbo].[Contacts]([ContactType], [CompanyName],
[Phone]) VALUES (@p0, @p1, @p2)

SELECT TOP (1) [t0].[ContactType], [t0].[ContactID],
[t0].[CompanyName], [t0].[Phone],[t0].[HomePage],
[t0].[ContactName], [t0].[ContactTitle], [t0].[Address],
[t0].[City],[t0].[Region], [t0].[PostalCode], [t0].[Country],
[t0].[Fax], [t0].[PhotoPath],[t0].[Photo], [t0].[Extension]
FROM [dbo].[Contacts] AS [t0]
WHERE ([t0].[CompanyName] = @p0) AND ([t0].[Phone] = @p1)
-- @p0: Input NVarChar (Size = 15; Prec = 0; Scale = 0)
    [Unknown Company]
-- @p1: Input NVarChar (Size = 12; Prec = 0; Scale = 0)
    [333-444-5555]

7.插入新的记录

这个例子说明如何插入发货人的联系方式的一条记录。

//1.在插入之前查询一下,没有数据
var ShipperContacts =
    from sc in db.Contacts.OfType<ShipperContact>()
    where sc.CompanyName == "Northwind Shipper"
    select sc;
//2.插入数据
ShipperContact nsc = new ShipperContact()
{
    CompanyName = "Northwind Shipper",
    Phone = "(123)-456-7890"
};
db.Contacts.InsertOnSubmit(nsc);
db.SubmitChanges();
//3.查询数据,有一条记录
ShipperContacts =
    from sc in db.Contacts.OfType<ShipperContact>()
    where sc.CompanyName == "Northwind Shipper"
    select sc;
//4.删除记录
db.Contacts.DeleteOnSubmit(nsc);
db.SubmitChanges();

生成SQL语句如下:

SELECT COUNT(*) AS [value] FROM [dbo].[Contacts] AS [t0]
WHERE ([t0].[CompanyName] = @p0) AND ([t0].[ContactType] = @p1) 
AND ([t0].[ContactType] IS NOT NULL)
-- @p0: Input NVarChar [Northwind Shipper]
-- @p1: Input NVarChar [Shipper]

INSERT INTO [dbo].[Contacts]([ContactType], [CompanyName], [Phone])
VALUES (@p0, @p1, @p2)
-- @p0: Input NVarChar  [Shipper]
-- @p1: Input NVarChar  [Northwind Shipper]
-- @p2: Input NVarChar  [(123)-456-7890]

SELECT COUNT(*) AS [value] FROM [dbo].[Contacts] AS [t0]
WHERE ([t0].[CompanyName] = @p0) AND ([t0].[ContactType] = @p1)
AND ([t0].[ContactType] IS NOT NULL)
-- @p0: Input NVarChar [Northwind Shipper]
-- @p1: Input NVarChar [Shipper]

DELETE FROM [dbo].[Contacts] WHERE ([ContactID] = @p0) AND
([ContactType] = @p1) AND ([CompanyName] = @p2) AND ([Phone] = @p3)
-- @p0: Input Int  [159]
-- @p1: Input NVarChar  [Shipper]
-- @p2: Input NVarChar  [Northwind Shipper]
-- @p3: Input NVarChar  [(123)-456-7890]
-- @p4: Input NVarChar  [Unknown]
-- @p5: Input NVarChar (Size = 8; Prec = 0; Scale = 0) [Supplier]
-- @p6: Input NVarChar (Size = 7; Prec = 0; Scale = 0) [Shipper]
-- @p7: Input NVarChar (Size = 8; Prec = 0; Scale = 0) [Employee]
-- @p8: Input NVarChar (Size = 8; Prec = 0; Scale = 0) [Customer]

分享到:
评论

相关推荐

    LINQ to SQL手册

    LINQ to SQL语句(1)之Where LINQ to SQL语句(2)之Select/Distinct LINQ to SQL语句(3)之Count/Sum/Min/Max/Avg LINQ to SQL语句(4)之Join LINQ to SQL语句(5)之Order By ...LINQ to SQL语句(25)之继承

    LINQ_to_SQL语法及实例大全

    LINQ to SQL语句(1)之Where 2 Where操作 2 1.简单形式: 2 ...LINQ to SQL语句(25)之继承 96 1.一般形式 97 2.OfType形式 98 3.IS形式 98 4.AS形式 99 5.Cast形式 99 6.UseAsDefault形式 100 7.插入新的记录 101

    Linq to Sql语句详解

    Linq to Sql语句详解,讲述了Linq to Sql语法详解,包括Linq to sql的动态语句,和继承的应用。还有在分层结构情况下的应用。

    LINQ基础教程(中文版) 适合初学者

    一步一步学Linq to sql(八):继承与关系 60 一步一步学Linq to sql(九):其它补充 69 一步一步学Linq to sql(十):分层构架的例子 73 Linq To Xml学习 80 Linq To Xml学习 - 1. 概述 80 Linq To Xml学习 - 2...

    LINQ中文系列教程

    一步一步学Linq to sql(八):继承与关系 60 一步一步学Linq to sql(九):其它补充 69 一步一步学Linq to sql(十):分层构架的例子 73 Linq To Xml学习 80 Linq To Xml学习 - 1. 概述 80 Linq To Xml学习 - 2...

    LINQ中文教程(WORD格式)

    一步一步学Linq to sql(八):继承与关系 60 一步一步学Linq to sql(九):其它补充 69 一步一步学Linq to sql(十):分层构架的例子 73 Linq To Xml学习 80 Linq To Xml学习 - 1. 概述 80 Linq To Xml学习 - 2...

    LINQ 实战 7/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 1/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 3/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 4/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 2/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 11/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 5/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 6/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 8/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 10/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    LINQ 实战 9/11

    8.2.1 使用SQL语句直接得到结果对象 209 8.2.2 使用存储过程 210 8.2.3 用户自定义函数 217 8.3 改进业务逻辑层 220 8.3.1 预编译的查询 220 8.3.2 使用部分类实现自定义业务逻辑 221 8.3.3 使用部分...

    Devart Entity Developer v6.0.67 Professional破解版

    它支持创建各种一映射,如表分割,映射实体到多个表,复杂类型,继承分层,从Select语句创建实体,从SQL代码创建方法等。由于使用了类似T4的模板,所以代码生成非常灵活,另外你还能创建自己的模板用于其他的编程...

    Devart Entity Developer v6.4.719 Professional破解版,支持vs2019

    它支持创建各种一映射,如表分割,映射实体到多个表,复杂类型,继承分层,从Sel ect语句创建实体,从SQL代码创建方法等。由于使用了类似T4的模板,所以代码生成非常灵活,另外你还能创建自己的模板用于其他的编程...

Global site tag (gtag.js) - Google Analytics