从(1)我们看到,当生成entity class定义时,entity class或xml mapping文件中都已经完整的包含了entity和关系数据库的映射信息了,LINQ2SQL会根据这些信息来把CRUD操作转化为SQL提交给数据库,并且把数据库的返回DataTable封装成我们想要的对象。
所谓简单对象,就是数据表定义中没有Foreign-key的entity class,在操作这类对象时不会涉及级联的操作。
简单对象的CRUD操作,可参考MSDN:http://msdn.microsoft.com/zh-cn/library/bb399349.aspx
有一点很方便,在插入数据时,LINQ2SQL不但生成了Insert的SQL语句,而且还生成语句把ColumnAttribute标记 IsDbGenerated=true的数据列取回。这点当我们用数据库生成的uniqueidentifier列或自增id做主键时尤其方便。
下面让我们来一起讨论级联操作以及相关问题,为了方便示例我定义了两张数据表Publishers和Books:
其中PublisherID和BookID都是RowGuid,而且默认值为newid(),以下代码都是基于SqlMetal生成的xml mapping和entity class。
添加
下面代码示例了在添加Publisher记录时,同时添加两个关联Book记录
1 var context = GenerateContext();
2 Publisher publisher = new Publisher { Name = "Microsoft" };
3 publisher.Books.Add(new Book { Title = "Expert F#" });
4 publisher.Books.Add(new Book { Title = "Beautiful code" });
5
6 context.Publishers.InsertOnSubmit(publisher);
7 context.SubmitChanges();
提交成功,关联对象的添加就好像是集合操作。但是,好像缺了点什么?我们好像没有给Book.PublisherID赋值,作为外键没有赋值为什么会没抛出异常呢?这都是生成代码的功劳,我们看看Publisher.Books属性的定义
1 private EntitySet<Book> _Books;
2
3 public Publisher()
4 {
5 this._Books = new EntitySet<Book>(
6 new Action<Book>(this.attach_Books), new Action<Book>(this.detach_Books));
7 OnCreated();
8 }
当向Books集合中添加元素时,会调用attach_Books让Book.Publisher指向Publisher对象