zoukankan      html  css  js  c++  java
  • Linq To Sql进阶系列(一)从映射讲起

    本系列,或多或少,直接或间接依赖入门系列知识。但,依然追求独立成章。因本文作者水平有限,文中错误难免,敬请读者指出并谅解。本系列将会和入门并存。

    案例
    某君被邀为一超市设计数据库,用来存储数据。该君根据该超市中实际出现的对象,设计了Customer, Employee,Order, Product等表,用来保存相应的客户,员工,订单,货品等。太好了,该君很有oo的思想吗。

    如果,你被要求用类及对象,来描述该关系型数据,你该如何做呢?在linq推出之前,ADO.NET被用来做数据访问层。而后,程序员需要自己去编写事务逻辑层中所出现的类。比如,Customer, Employee,Order, Product等。然后,程序员组装所需的sql语句,通过ADO.NET,将返回的记录,来初始化Customer等类的对象。在这里,你已经自己动手将Customer表和Customer类关联了起来。从Linq To Sql的设计来看,它主要是为了解决data!=objects 的问题而产生的。现在,有了Table和Class之间的映射,数据和对象之间就可以有一个一一对应的关系了。
    在Linq To Sql之前,在java领域有Hibernate,在net领域有NHibernate技术,来实现object/relational 持久和查询服务。无论是Hibernate还是NHibernate,其配置复杂,上手时间长,已经不能适应快速开发的需要。而Linq To Sql的推出,恰恰弥补了它们的缺点,彻底降低了程序开发门槛。

    Linq
    Linq是Language Integrated Query的缩写。Linq To Sql是linq中的一部分,其与ADO.NET Orcas的关系入下。

    现在linq分三个部分。Linq To Objects,即以前的linq。其主要是针对CLR-Based Objects的查询。即内存操作。Linq Enabled ADO.NET是针对关系型数据的。这又包含三个部分。Linq To Datasets, Linq To Sql, Linq To Entities. 其中Linq To Sql 是大家所熟悉的部分,即以前的Dlinq. 官方的解释是,Linq To Datasets, support for ADO.NET Datasets; Linq to SQL, support for SQL Server; Linq to Entities, Support fro Entity Data Model. 记得,以前曾有人问及dlinq与ADO.NET Orcas的关系,因为它们隶属于不同的队伍开发,其中有重叠的部分。而现在,其功能归结在一起,其重叠部分已经得到融合。(如果有人是ADO.NET team或熟悉这个的,开辟专栏给我们大家讲一下呀。)最后一部分叫Linq To XML,即以前的Xlinq. 针对xml格式数据的操作。(还有针对ASP.NET的Blinq, 大声问一下,有没有人懂这个呀)

    DBML
    所谓dbml,即Database Mark Language。数据库描述语言,是一种xml格式的文档,用来描述数据库。上面我们讲了,不是用类来描述数据吗?为什么又有个dbml?是的,dbml只是个中间的产物,其出现的主要原因是,适应c# 和vb.net语言的不同,做中间缓冲。dbml及数据库和code关系如下。
    Database ----> DBML ------------> Code.
    使用sqlmetal可以产生dbml。键入如下命令:
    sqlmetal /server:yourserver /database:northwind /dbml:YourDbml.dbml
    最终可以得到dbml文件,如下:


    也可以使用该dbml生成code,命令如下,可以用language选项,控制生成vb.net或c#语言的代码。
    sqlmetal YourDbml.dbml /code: nwind.cs

    C#3.0入门系列(七)--之OR工具介绍 一文中,我们介绍了OR Designer工具,它生成的就是dbml,可以使用记事本打开DataClasses1.dbml 文件来看。有些属性,是无法从数据库中抽提出来的,比如继承,等。而我们又想对其映射做继承,就需要我们自己手工去修改dbml。好在OR Designer提供这些功能(以后再介绍)。

    关系型数据的映射
    数据间的关系,有2种基本关系。1: 1 和1: M。可以参阅C# 3.0入门系列(二)一文,查阅northwind数据库中的关系图。本文用Order 和Order Detail 表,来阐述其关系的映射。Order 为订单,Order Detail 为订单详情。其关系形式为,一条Order记录对应多条Order Detail 记录。
    你可以在上面产生的code中,找到相应的order类,其中有这么一段

        [Table(Name="Orders")]
        
    public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged
        
    {
            [Association(Name
    ="Order_OrderDetail", Storage="_OrderDetails", OtherKey="OrderID")]
            
    public EntitySet<OrderDetail> OrderDetails
            
    {
                
    get
                
    {
                    
    return this._OrderDetails;
                }

                
    set
                
    {
                    
    this._OrderDetails.Assign(value);
                }

            }

            
    }

    在Order类中,有个property,叫OrderDetails,是EntitySet<OrderDetail> 类型的。EntitySet是个集合类型的模板。 其继承关系如下
     EntitySet<TEntity> : IList, ICollection, IList<TEntity>, ICollection<TEntity>, IEnumerable<TEntity>, IEnumerable, IListSource where TEntity : class

    在OrderDetails类中,也可以找到这么一段。

        [Table(Name="Order Details")]
        
    public partial class OrderDetail : INotifyPropertyChanging, INotifyPropertyChanged
        
    {

            
    private EntityRef<Order> _Order;
            [Association(Name
    ="Order_OrderDetail", Storage="_Order", ThisKey="OrderID", IsForeignKey=true)]
            
    public Order Order
            
    {
                
    get
                
    {
                    
    return this._Order.Entity;
                }

                
    set
                
    {
                    Order previousValue 
    = this._Order.Entity;
                    
    if (((previousValue != value) 
                                
    || (this._Order.HasLoadedOrAssignedValue == false)))
                    
    {
                        
    this.SendPropertyChanging();
                        
    if ((previousValue != null))
                        
    {
                            
    this._Order.Entity = null;
                            previousValue.OrderDetails.Remove(
    this);
                        }

                        
    this._Order.Entity = value;
                        
    if ((value != null))
                        
    {
                            value.OrderDetails.Add(
    this);
                            
    this._OrderID = value.OrderID;
                        }

                        
    else
                        
    {
                            
    this._OrderID = default(int);
                        }

                        
    this.SendPropertyChanged("Order");
                    }

                }

            }

            
    }

    也就是说Order 在OrderDetail类中,是以EntityRef出现的。这样,在关系双方的各端,我们使用EntityRef和EntitySet来表示其关系。简言之,One在Many端,以EntityRef出现,而Many在One端,以EntitySet出现。上例中,在property 中,因其返回的是this._Order.Entity,直接返回的是Order。
    对于1:1的关系,双双彼此在各自的类中,均以EntityRef出现。大家可以自己试。这样,Order和 OrderDetail
    的关系,在各自的类中,都有了体现。体现方式的不同,反映了它们关系主体的不同。

    TrackBack:http://www.cnblogs.com/126/archive/2007/07/11/813218.html

  • 相关阅读:
    Codeforces Round 546 (Div. 2)
    Codeforces Round 545 (Div. 2)
    Codeforces Round 544(Div. 3)
    牛客小白月赛12
    Codeforces Round 261(Div. 2)
    Codeforces Round 260(Div. 2)
    Codeforces Round 259(Div. 2)
    Codeforces Round 258(Div. 2)
    Codeforces Round 257 (Div. 2)
    《A First Course in Probability》-chaper5-连续型随机变量-随机变量函数的分布
  • 原文地址:https://www.cnblogs.com/hdjjun/p/1327133.html
Copyright © 2011-2022 走看看