Linq To Sql进阶系列(一)从映射讲起
系列文章导航:
Linq To Sql进阶系列(四)User Define Function篇
Linq To Sql进阶系列(五)Store Procedure篇
Linq To Sql进阶系列(六)用object的动态查询与保存log篇
Linq To Sql进阶系列(七)动态查询续及CLR与SQL在某些细节上的差别
关系型数据的映射
数据间的关系,有2种基本关系。1: 1 和1: M。查阅northwind数据库中的关系图。本文用Order 和Order Detail 表,来阐述其关系的映射。Order 为订单,Order Detail 为订单详情。其关系形式为,一条Order记录对应多条Order Detail 记录。
你可以在上面产生的code中,找到相应的order类,其中有这么一段
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类中,也可以找到这么一段。
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
的关系,在各自的类中,都有了体现。体现方式的不同,反映了它们关系主体的不同。