光脚丫学LINQ(017):跨关系查询(C#):手动编码

视频演示:http://u.115.com/file/f2e338988d

本演练演示如何使用 LINQ to SQL 关联来表示数据库中的外键关系。

此演示是建立在前一个演示的基础上。光脚丫学LINQ(016):[演练]创建简单对象模型和LINQ查询(C#),你可以通过这个链接转到前一个演示。


跨表映射关系
在 Customer 类定义的后面,创建包含如下代码的 Order 实体类定义,这些代码表示 Order.Customer 作为外键与 Customer.CustomerID 相关。
在 Customer 类后面键入或粘贴如下代码:

[Table(Name = "Orders")]   
public class Order   
{   
    private int _OrderID = 0;   
    private string _CustomerID;   
    private EntityRef <Customer> _Customer;   
  
    public Order() { this._Customer = new EntityRef<Customer>(); }   
  
    [Column(Storage = "_OrderID", DbType = "Int NOT NULL IDENTITY",   
        IsPrimaryKey = true, IsDbGenerated = true)]   
    public int OrderID   
    {   
        get { return this._OrderID; }   
        // No need to specify a setter because IsDBGenerated is   
        // true.   
    }   
  
    [Column(Storage = "_CustomerID", DbType = "NChar(5)")]   
    public string CustomerID   
    {   
        get { return this._CustomerID; }   
        set { this._CustomerID = value; }   
    }   
  
    [Association (Storage = "_Customer", ThisKey  = "CustomerID")]   
    public Customer Customer   
    {   
        get { return this._Customer.Entity; }   
        set { this._Customer.Entity = value; }   
    }   
}  
[Table(Name = "Orders")]
public class Order
{
    private int _OrderID = 0;
    private string _CustomerID;
    private EntityRef <Customer> _Customer;

    public Order() { this._Customer = new EntityRef<Customer>(); }

    [Column(Storage = "_OrderID", DbType = "Int NOT NULL IDENTITY",
        IsPrimaryKey = true, IsDbGenerated = true)]
    public int OrderID
    {
        get { return this._OrderID; }
        // No need to specify a setter because IsDBGenerated is
        // true.
    }

    [Column(Storage = "_CustomerID", DbType = "NChar(5)")]
    public string CustomerID
    {
        get { return this._CustomerID; }
        set { this._CustomerID = value; }
    }

    [Association (Storage = "_Customer", ThisKey  = "CustomerID")]
    public Customer Customer
    {
        get { return this._Customer.Entity; }
        set { this._Customer.Entity = value; }
    }
}


对Customer类进行批注
在此步骤中,您要对 Customer 类进行批注,以指示它与 Order 类的关系。 (这种添加批注的操作并非绝对必需的,因为定义任一方向上的关系都足以满足创建链接的需要。 但添加此批注确实便于您在任一方向上定位对象。)
将下面的代码键入或粘贴到 Customer 类中:

private EntitySet <Order> _Orders;   
public Customer()   
{   
    this._Orders = new EntitySet<Order>();   
}   
  
[Association(Storage = "_Orders", OtherKey  = "CustomerID")]   
public EntitySet<Order> Orders   
{   
    get { return this._Orders; }   
    set { this._Orders.Assign(value); }   
}  
private EntitySet <Order> _Orders;
public Customer()
{
    this._Orders = new EntitySet<Order>();
}

[Association(Storage = "_Orders", OtherKey  = "CustomerID")]
public EntitySet<Order> Orders
{
    get { return this._Orders; }
    set { this._Orders.Assign(value); }
}


跨 Customer-Order 关系创建并运行查询
现在您可以直接从 Customer 对象访问 Order 对象,或反过来进行访问。 您不需要在客户和订单之间具有显式联接。
使用Customer对象访问Order对象
1、 通过将下面的代码键入或粘贴到 Main 方法中修改此方法:

// Query for customers who have placed orders.   
var CustomersHasOrders =   
    from CustomerObject in Customers   
    where CustomerObject.Orders.Any()   
    select CustomerObject;   
  
foreach (var CustomerObject in CustomersHasOrders)   
{   
    Console.WriteLine("ID={0}, Qty={1}",   
        CustomerObject.CustomerID,   
        CustomerObject.Orders.Count);   
}  
// Query for customers who have placed orders.
var CustomersHasOrders =
    from CustomerObject in Customers
    where CustomerObject.Orders.Any()
    select CustomerObject;

foreach (var CustomerObject in CustomersHasOrders)
{
    Console.WriteLine("ID={0}, Qty={1}",
        CustomerObject.CustomerID,
        CustomerObject.Orders.Count);
}

2、 按 F5 调试应用程序。
说明
您可以通过注释掉 db.Log = Console.Out; 来消除控制台窗口中的 SQL 代码。
3、 在控制台窗口中按 Enter,以停止调试。


创建数据库的强类型化视图
从数据库的强类型化视图着手要容易得多。 通过将 DataContext 对象强类型化,您无需调用 GetTable。 当您使用强类型化的 DataContext 对象时,您可以在所有查询中使用强类型化表。
在以下步骤中,您将创建 Customers 作为映射到数据库中的 Customers 表的强类型化表。
对 DataContext 对象进行强类型化
1、 将下面的代码添加到 Customer 类声明的上方。

public class Northwind : DataContext   
{   
    // Table<T> abstracts database details per table/data type.   
    public Table<Customer> Customers;   
    public Table<Order> Orders;   
  
    public Northwind(string connection) : base(connection) { }   
}  
public class Northwind : DataContext
{
    // Table<T> abstracts database details per table/data type.
    public Table<Customer> Customers;
    public Table<Order> Orders;

    public Northwind(string connection) : base(connection) { }
}

2、 将 Main 方法修改为使用强类型化的 DataContext,如下所示:

// Use a connection string.   
Northwind db = new Northwind(@"C:\linqtest5\Northwind.mdf");   
  
// Query for customers from Seattle.    
var SeattleCustomers =   
    from CustomerObject in db.Customers   
    where CustomerObject.City == "Seattle"  
    select CustomerObject;   
  
foreach (var CustomerObject in SeattleCustomers)   
{   
    Console.WriteLine("ID={0}", CustomerObject.CustomerID);   
}   
  
// Freeze the console window.   
Console.ReadLine();  
// Use a connection string.
Northwind db = new Northwind(@"C:\linqtest5\Northwind.mdf");

// Query for customers from Seattle. 
var SeattleCustomers =
    from CustomerObject in db.Customers
    where CustomerObject.City == "Seattle"
    select CustomerObject;

foreach (var CustomerObject in SeattleCustomers)
{
    Console.WriteLine("ID={0}", CustomerObject.CustomerID);
}

// Freeze the console window.
Console.ReadLine();

完整的演示代码如下:

Program.cs

using System;   
using System.Collections.Generic;   
using System.Linq;   
using System.Text;   
using System.Data.Linq;   
using System.Data.Linq.Mapping;   
  
namespace Demo02   
{   
    [Table(Name = "Customers")]   
    public class Customer   
    {   
        private string _CustomerID;   
        [Column(IsPrimaryKey = true, Storage = "_CustomerID")]   
        public string CustomerID   
        {   
            get  
            {   
                return this._CustomerID;   
            }   
            set  
            {   
                this._CustomerID = value;   
            }   
        }   
  
        private string _City;   
        [Column(Storage = "_City")]   
        public string City   
        {   
            get  
            {   
                return this._City;   
            }   
            set  
            {   
                this._City = value;   
            }   
        }   
  
        private EntitySet<Order> _Orders;   
        public Customer()   
        {   
            this._Orders = new EntitySet<Order>();   
        }   
  
        [Association(Storage = "_Orders", ThisKey = "CustomerID", OtherKey = "CustomerID")]   
        public EntitySet<Order> Orders   
        {   
            get { return this._Orders; }   
            set { this._Orders.Assign(value); }   
        }   
    }   
  
    [Table(Name = "Orders")]   
    public class Order   
    {   
        private int _OrderID = 0;   
        private string _CustomerID;   
        private EntityRef<Customer> _Customer;   
  
        public Order() { this._Customer = new EntityRef<Customer>(); }   
  
        [Column(Storage = "_OrderID", DbType = "Int NOT NULL IDENTITY",   
            IsPrimaryKey = true, IsDbGenerated = true)]   
        public int OrderID   
        {   
            get { return this._OrderID; }   
            // No need to specify a setter because IsDBGenerated is   
            // true.   
        }   
  
        [Column(Storage = "_CustomerID", DbType = "NChar(5)")]   
        public string CustomerID   
        {   
            get { return this._CustomerID; }   
            set { this._CustomerID = value; }   
        }   
  
        [Association(Storage = "_Customer", ThisKey = "CustomerID", OtherKey = "CustomerID")]   
        public Customer Customer   
        {   
            get { return this._Customer.Entity; }   
            set { this._Customer.Entity = value; }   
        }   
    }   
  
  
    class Program   
    {   
        static void Main(string[] args)   
        {   
            // *************************************************   
            // 跨关系查询。   
            // *************************************************   
            // Use a connection string.   
            DataContext db = new DataContext(@"C:\linqtest5\Northwind.mdf");   
  
            // Get a typed table to run queries.   
            Table<Customer> Customers = db.GetTable<Customer>();   
  
            // Attach the log to show generated SQL.   
            //db.Log = Console.Out;   
  
            // Query for customers who have placed orders.   
            var CustomersHasOrders =   
                from CustomerObject in Customers   
                where CustomerObject.Orders.Any()   
                select CustomerObject;   
  
            foreach (var CustomerObject in CustomersHasOrders)   
            {   
                Console.WriteLine("ID={0}, Qty={1}",   
                    CustomerObject.CustomerID,   
                    CustomerObject.Orders.Count);   
                //Console.WriteLine(CustomerObject.Orders[0].Customer.CustomerID);   
            }   
  
            // Prevent console window from closing.   
            Console.ReadLine();   
  
  
            // *************************************************   
            // 使用强类型的数据上下文。   
            // *************************************************   
            // Use a connection string.   
            //Northwind db = new Northwind(@"C:\linqtest5\Northwind.mdf");   
  
            //// Query for customers from Seattle.    
            //var SeattleCustomers =   
            //    from CustomerObject in db.Customers   
            //    where CustomerObject.City == "Seattle"   
            //    select CustomerObject;   
  
            //foreach (var CustomerObject in SeattleCustomers)   
            //{   
            //    Console.WriteLine("ID={0}", CustomerObject.CustomerID);   
            //}   
  
            //// Freeze the console window.   
            //Console.ReadLine();   
        }   
    }   
}  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace Demo02
{
    [Table(Name = "Customers")]
    public class Customer
    {
        private string _CustomerID;
        [Column(IsPrimaryKey = true, Storage = "_CustomerID")]
        public string CustomerID
        {
            get
            {
                return this._CustomerID;
            }
            set
            {
                this._CustomerID = value;
            }
        }

        private string _City;
        [Column(Storage = "_City")]
        public string City
        {
            get
            {
                return this._City;
            }
            set
            {
                this._City = value;
            }
        }

        private EntitySet<Order> _Orders;
        public Customer()
        {
            this._Orders = new EntitySet<Order>();
        }

        [Association(Storage = "_Orders", ThisKey = "CustomerID", OtherKey = "CustomerID")]
        public EntitySet<Order> Orders
        {
            get { return this._Orders; }
            set { this._Orders.Assign(value); }
        }
    }

    [Table(Name = "Orders")]
    public class Order
    {
        private int _OrderID = 0;
        private string _CustomerID;
        private EntityRef<Customer> _Customer;

        public Order() { this._Customer = new EntityRef<Customer>(); }

        [Column(Storage = "_OrderID", DbType = "Int NOT NULL IDENTITY",
            IsPrimaryKey = true, IsDbGenerated = true)]
        public int OrderID
        {
            get { return this._OrderID; }
            // No need to specify a setter because IsDBGenerated is
            // true.
        }

        [Column(Storage = "_CustomerID", DbType = "NChar(5)")]
        public string CustomerID
        {
            get { return this._CustomerID; }
            set { this._CustomerID = value; }
        }

        [Association(Storage = "_Customer", ThisKey = "CustomerID", OtherKey = "CustomerID")]
        public Customer Customer
        {
            get { return this._Customer.Entity; }
            set { this._Customer.Entity = value; }
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            // *************************************************
            // 跨关系查询。
            // *************************************************
            // Use a connection string.
            DataContext db = new DataContext(@"C:\linqtest5\Northwind.mdf");

            // Get a typed table to run queries.
            Table<Customer> Customers = db.GetTable<Customer>();

            // Attach the log to show generated SQL.
            //db.Log = Console.Out;

            // Query for customers who have placed orders.
            var CustomersHasOrders =
                from CustomerObject in Customers
                where CustomerObject.Orders.Any()
                select CustomerObject;

            foreach (var CustomerObject in CustomersHasOrders)
            {
                Console.WriteLine("ID={0}, Qty={1}",
                    CustomerObject.CustomerID,
                    CustomerObject.Orders.Count);
                //Console.WriteLine(CustomerObject.Orders[0].Customer.CustomerID);
            }

            // Prevent console window from closing.
            Console.ReadLine();


            // *************************************************
            // 使用强类型的数据上下文。
            // *************************************************
            // Use a connection string.
            //Northwind db = new Northwind(@"C:\linqtest5\Northwind.mdf");

            //// Query for customers from Seattle. 
            //var SeattleCustomers =
            //    from CustomerObject in db.Customers
            //    where CustomerObject.City == "Seattle"
            //    select CustomerObject;

            //foreach (var CustomerObject in SeattleCustomers)
            //{
            //    Console.WriteLine("ID={0}", CustomerObject.CustomerID);
            //}

            //// Freeze the console window.
            //Console.ReadLine();
        }
    }
}

Northwind.cs

using System;   
using System.Collections.Generic;   
using System.Linq;   
using System.Text;   
using System.Data.Linq;   
  
namespace Demo02   
{   
    public class Northwind : DataContext   
    {   
        // Table<T> abstracts database details per table/data type.   
        public Table<Customer> Customers;   
        public Table<Order> Orders;   
  
        public Northwind(string connection) : base(connection) { }   
    }   
}
原文地址:https://www.cnblogs.com/GJYSK/p/1864923.html