zoukankan      html  css  js  c++  java
  • LINQ体验(18)——LINQ to SQL语句之视图和继承支持

    视图

    我们使用视图和使用数据表类似,仅仅需将视图从“server资源管理器/数据库资源管理器”拖动到O/R 设计器上,自己主动能够创建基于这些视图的实体类。我们能够同操作数据表一样来操作视图了。这里注意:O/R 设计器是一个简单的对象关系映射器,由于它仅支持 1:1 映射关系。换句话说,实体类与数据库表或视图之间仅仅能具有 1:1 映射关系。

    不支持复杂映射(比如,将一个实体类映射到多个表)。可是,能够将一个实体类映射到一个联接多个相关表的视图。 以下使用NORTHWND数据库中自带的Invoices、Quarterly Orders两个视图为例,写出两个范例。

    查询:匿名类型形式

    我们使用以下代码来查询出ShipCity 在London的发票。

    var q =
        from i in db.Invoices
        where i.ShipCity == "London"
        select new
        {
            i.OrderID,
            i.ProductName,
            i.Quantity,
            i.CustomerName
        };

    这里。生成的SQL语句同使用数据表类似:

    SELECT [t0].[OrderID], [t0].[ProductName], [t0].[Quantity],
    [t0].[CustomerName] FROM [dbo].[Invoices] AS [t0]
    WHERE [t0].[ShipCity] = @p0
    -- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London]

    查询:标识映射形式

    下例查询出每季的订单。

    var q =
        from qo in db.Quarterly_Orders
        select qo;

    生成SQL语句为:

    SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[City],
    [t0].[Country] FROM [dbo].[Quarterly Orders] AS [t0]

    继承支持

    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语句,这样easy理解。在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]
  • 相关阅读:
    嵌入式Linux的启动过程
    【转载】vim 中文帮助手册的安装
    面向对象之编写驱动程序--中断(linux系统、s3c6410开发板)
    【转】DBCC IND / DBCC PAGE
    【转】索引查询 sys.dm_db_index_physical_stats
    【tag】Enum.HasFlag 方法
    【tag】Tuple 类 使用介绍
    【fixed point】柯里化(currying) C#实现
    SqlDataAdapter 批量更新 DataTable
    sqlCacheDependency 使用
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6816456.html
Copyright © 2011-2022 走看看