DLINQ的新功能

在五月份这个版本里,DLINQ提供了下面这些新功能(详情参考《DLinq Overview for CSharp Developers.doc》第七章“New Features in May 2006 Preview”)

1。支持继承,目前只支持单表继承
2。对多层应用的支持,DataContext对象多了一个Attach()方法,可在不同层或不同请求中更新实体对象
3。对远程和本地实体集合的支持。实体集合实现了IQueryable<T> ,确保过滤性查询在数据库端完成
4。支持Join,这样你能做这样的查询

var q = from s in db.Suppliers
 join c in db.Customers on s.City equals c.City
 select new {
  Supplier = s.CompanyName,
  Customer = c.CompanyName,
  City = c.City
 };

5。对外部XML映射文件的支持

编码调用

String path = @”C:\Mapping\NorthwindMapping.xml”;
XmlMappingSource prodMapping =
 XmlMappingSource.FromXml(File.ReadAllText(path));
Northwind db = new Northwind(
 @”Server=.\SQLExpress;Database=c:\Northwind\Northwnd.mdf”,
 prodMapping
 );

映射文件

<Database Name=”Northwind”>
 <Table Name=”Products“>
  <Type Name=”Mapping.Product“>
   <Column Name=”ProductID” Member=”ProductID” Storage=”_ProductID”
    DbType=”Int NOT NULL IDENTITY” IsIdentity=”True”
    IsAutoGen=”True” />
   <Column Name=”ProductName” Member=”ProductName”
    Storage=”_ProductName” DbType=”NVarChar(40) NOT NULL” />
   <Column Name=”SupplierID” Member=”SupplierID” Storage=”_SupplierID”
    DbType=”Int” />
….. 
   <Association Name=”FK_Order_Details_Products” Member=”OrderDetails”
    Storage=”_OrderDetails” ThisKey=”ProductID”
    OtherTable=”Order Details” OtherKey=”ProductID” />
   <Association Name=”FK_Products_Categories” Member=”Category”
…..
  </Type>
 </Table>
 <Table Name=”Order Details”>
  <Type Name=”Mapping.OrderDetail”>
…..    
  </Type>
 </Table>

 …
</Database>

6。对存储过程以及自定义函数的支持

存储过程:

CREATE PROCEDURE GetCustomerOrderCount(@CustomerID nchar(5))
AS
Declare @count int
SELECT @count = COUNT(*) FROM ORDERS WHERE CustomerID = @CustomerID
RETURN @count

映射方法:

[StoredProcedure(Name=”GetCustomerOrderCount”)]
public int GetCustomerOrderCount(
 [Parameter(Name=”CustomerID”)] string customerID
 )
{
 StoredProcedureResult result = this.ExecuteStoredProcedure(
  ((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);

 return result.ReturnValue.Value;
}

7。提供了一个DLinq Query Visualizer,在调试时查看实际SQL语句以及参数情形

8。新添加了一个设计器,用于设计类(表)间关系以及生成编码

在项目里添加一个DLinqObjects模块,然后把Northwind数据库里的2个类Customers和Orders两个表先后拖到DLinq设计器上,设计器会根据数据库里的关系自动建立关联,同时生成下列编码

namespace LINQConsoleApplication1 { 
   
    public partial class NorthwindDataContext : System.Data.DLinq.DataContext {
       
        public System.Data.DLinq.Table<Customer> Customers;
        public System.Data.DLinq.Table<Order> Orders;   
…..
   
    [System.Data.DLinq.Table(Name=”Customers”)]
    public partial class Customer : System.Data.DLinq.INotifyPropertyChanging,

System.ComponentModel.INotifyPropertyChanged {
        private string _CustomerID;    
…..  
        private System.Data.DLinq.EntitySet<Order> _Orders;
       
…..     
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [System.Data.DLinq.Association(Name=”FK_Orders_Customers”, Storage=”_Orders”, OtherKey=”CustomerID”)]
        public virtual System.Data.DLinq.EntitySet<Order> Orders {
            get {
                return this._Orders;
            }
            set {
                this._Orders.Assign(value);
            }
        }
…..
    }
   
    [System.Data.DLinq.Table(Name=”Orders”)]
    public partial class Order : System.Data.DLinq.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged

{
       
        private int _OrderID;
…..
        private System.Data.DLinq.EntityRef<Customer> _Customer;
…..
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [System.Data.DLinq.Association(Name=”FK_Orders_Customers”, Storage=”_Customer”, ThisKey=”CustomerID”,

IsParent=true)]
        public Customer Customer {
            get {
                return this._Customer.Entity;
            }
            set {
                if ((this._Customer.Entity != value)) {
                    this.OnPropertyChanging(“Customer”);
                    if ((this._Customer.Entity != null)) {
                        this._Customer.Entity = null;
                        this._Customer.Entity.Orders.Remove(this);
                    }
                    this._Customer.Entity = value;
                    if ((value != null)) {
                        value.Orders.Add(this);
                    }
                    this.OnPropertyChanged(“Customer”);
                }
            }
        }
…..
    }

假设你有类似这样的数据表Person,当Type为2时表明是Employee

字段名 数据类型 允许空
Type int True
ID(主键) int False
FirstName nvarchar(200) False
LastName nvarchar(200) False
Manager int True

拖动2份Person到设计器,把第二份改名为Employee

把Manager属性从Person类删去,从Employee类,保持Manager属性,删去其他的属性,从工具箱里选择“继承”连接,然后依次选择Employee类,Person类,建立继承关系

设置DiscriminatorColumn为Type,把Employee的DiscriminatorValue设置为2,把Person的DiscriminatorValue设置为1,保存后,会生成下列编码

[System.Data.DLinq.InheritanceMapping(Code=1, Type=typeof(Person), IsDefault=true)]
[System.Data.DLinq.InheritanceMapping(Code=2, Type=typeof(Employee))]
[System.Data.DLinq.Table(Name=”Person”)]
public partial class Person : System.Data.DLinq.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged {  

…..
    }
   
    public partial class Employee : Person {
       
        private System.Nullable<int> _Manager;
…..
    }
}