Linq To Sql进阶系列(三)CUD和Log

CUD就是Create, Update, Delete。在别人都写过了后,还有什么是新鲜的呢?

  1,
  
  
CreateDatabase Northwind db = new Northwind("You connection string"); // 注意database项,起一个
不存在的数据库名称 db. Log = Console.Out; if (!db.DatabaseExists()) // 如果,数据库不存在 db.CreateDatabase(); // 创建数据库


    这个的好处,就是你可以用OR designer设计实体类,定义其在数据库的各个column,然后,将其返回到数据库。前段时间,和别人争论起,在程序设计时,是先有实体类还是先有实体表时,其主张,是由高层到底层,即先设计实体类,再做表。那这个恰好满足了这个需要。但是,在OR designer上设计实体类的数据库属性时,及其难用,我宁愿根据实体类,去设计数据库中的表,然后,在重新生成这些实体类。

  2, Inser记录 
  2.0
  这个操作相当简单。new出来一个对象,使用Add方法将其加入到其对应Entity集合中后,使用SubmitChanges函数即可。
  
  
var newCustomer = new Customer { CustomerID = "MCSFT", CompanyName = "Microsoft", ContactName = "John Doe", ContactTitle = "Sales Manager", Address = " 1 Microsoft Way", City = "Redmond", Region = "WA", PostalCode = " 98052 ", Country = "USA", Phone = "( 425 ) 555 - 1234 ", Fax = null }; db.Customers. Add (newCustomer); db.SubmitChanges();
  2.1
  如果,数据表中有数据库自动赋值的column的呢?就拿Orders表来说事。其OrderID就是自增型的。看看该字段的映射。
  
  
[Column(Storage = " _OrderID " , AutoSync = AutoSync.OnInsert, DbType = " Int NOT NULL
IDENTITY " , IsPrimaryKey = true , IsDbGenerated = true )] public int OrderID { get { return this ._OrderID; } set { if (( this ._OrderID != value)) { this .OnOrderIDChanging(value); this .SendPropertyChanging(); this ._OrderID = value; this .SendPropertyChanged( " OrderID " ); this .OnOrderIDChanged(); } } }
  在其Attribute中,有AutoSync=AutoSync.OnInsert. 当有IsDbGenerated为true时,OnInsert为AutoSync默认值。该字段告诉run-time,在插入数据库后,自动更新数据库产生的值。 我们随便来做个测试,看看Linq To Sql做了什么。
  
  
Orders o = new Orders(); o.ShipAddress = "Test"; db.Orders. Add (o); db.SubmitChanges(); Console.WriteLine(o.OrderID);
  你可以扑获如下的sql
  
  
INSERT INTO [ dbo ] . [ Orders ] ( [ CustomerID ] , [ EmployeeID ] , [ OrderDate ] ,
[ RequiredDate ] , [ ShippedDate ] , [ ShipVia ] , [ Freight ] , [ ShipName ] , [ ShipAddress ] ,
[ ShipCity ] , [ ShipRegion ] , [ ShipPostalCode ] , [ ShipCountry ] )
VALUES ( @p0 , @p1 , @p2 , @p3 , @p4 , @p5 , @p6 , @p7 , @p8 , @p9 , @p10 , @p11 , @p12 ) SELECT [ t0 ] . [ OrderID ] FROM [ dbo ] . [ Orders ] AS [ t0 ] WHERE [ t0 ] . [ OrderID ] = ( SCOPE_IDENTITY ()) -- @p0: Input StringFixedLength (Size = 5; Prec = 0; Scale = 0) [] -- @p1: Input Int32 (Size = 0; Prec = 0; Scale = 0) [] -- @p2: Input DateTime (Size = 0; Prec = 0; Scale = 0) [] -- @p3: Input DateTime (Size = 0; Prec = 0; Scale = 0) [] -- @p4: Input DateTime (Size = 0; Prec = 0; Scale = 0) [] -- @p5: Input Int32 (Size = 0; Prec = 0; Scale = 0) [] -- @p6: Input Currency (Size = 0; Prec = 19; Scale = 4) [] -- @p7: Input String (Size = 0; Prec = 0; Scale = 0) [] -- @p8: Input String (Size = 4; Prec = 0; Scale = 0) [Test] -- @p9: Input String (Size = 0; Prec = 0; Scale = 0) [] -- @p10: Input String (Size = 0; Prec = 0; Scale = 0) [] -- @p11: Input String (Size = 0; Prec = 0; Scale = 0) [] -- @p12: Input String (Size = 0; Prec = 0; Scale = 0) [] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.20706.1
这表明Linq To Sql自动更新了该对象,把数据库自增字段的值取出,赋于该对象。从这里,也可以看出,Linq To Sql在插入数据时,自动调用了事务,以防止返回的不是其插入的。

  2.2
  对与One : Many的关系型的,在提交One端新数据时,Linq To Sql会自动将Many端的数据一起提交。注意,是提交One端哦。比如
  
  
var newCategory = new Category { CategoryName = "Widgets", Description = "Widgets are the customer - facing analogues " + " to sprockets and cogs." }; var newProduct = new Product { ProductName = "Blue Widget", UnitPrice = 34.56M, Category = newCategory }; db2.Categories. Add (newCategory); db2.SubmitChanges();
  2.3
  而对于Many : Many的关系(关于M:M请参考上篇),就需要你从One 一个个开始,一直到Many端,自己去提交了。如:
  
  
var newEmployee = new Employee { FirstName = "Kira", LastName = "Smith" }; var newTerritory = new Territory { TerritoryID = " 12345 ", TerritoryDescription = "Anytown", Region = db.Regions.First() }; var newEmployeeTerritory = new EmployeeTerritory { Employee = newEmployee, Territory = newTerritory }; db.Employees. Add (newEmployee); db.Territories. Add (newTerritory); db.EmployeeTerritories. Add (newEmployeeTerritory); db.SubmitChanges();
  3, Update
  这个更简单,用Linq To Sql获取对象后,进行一系列处理后,做更新,直接调用DataContext中的SubmitChanges方法。我们来讲一个在不同 DataContext之间,更新的问题。涉及到不同的DataContext,就要使用Attach方法了。在使用Attach方法时,请在其实体类的主键的Attribute上,添加IsVersion=true,比如:[Column(Storage="_PageID"...., IsVersion=true)] 。这样,另外一个DataContext才知道,该对象是否需要更新。大家需要注意的是,在更新问题上,对谁更新,就直接Attach谁。比如,有A和B 两个实体,他们之间是有关系的。对A更新直接对A操作,而不是对B操作。见例子:
  
  
nwind.Order o = null ; using (nwind.Northwind db = new nwind.Northwind(constr)) { o = db.Orders.First(); o.Customer.City = " new city " ; // db.SubmitChanges(); // 此处提交是没有问题的。 } using (nwind.Northwind db = new nwind.Northwind(constr)) { db.Log = Console.Out; db.Orders.Attach(o, true ); // 对Customer进行更新,却Attach了Order,其结果,
只是在数据库中insert一个新的Customer // db.Customers.Attach(o.Customer, true); // 这个是对的。 db.SubmitChanges();
  4, Delete
  Delete 使用Remove方法。唯一可以讲的是,在One:Many的关系中,需要先Remove其Many端,其次才是One端。道理很简单,One端是主键呀,只要Many端还有一个和该键相关的记录,服务器是不会允许你删除该主键的。比如:
  
  
var order = ( from o in db.Orders where o.CustomerID == "WARTH" && o.EmployeeID == 3 select o).First(); foreach (OrderDetail od in orderDetails) { db.OrderDetails.Remove(od); } db.Orders.Remove( order ); db.SubmitChanges();
  5, Log
  Log吗,顾名思义,就是日志。其记录了Linq To Sql的所有操作。我们可以将起写入文件,以备检查对数据库的操作。比如:
  
  
StreamWriter sw = new StreamWriter( " log.txt " , true ); db.Log = sw; var q = db.Customers.Select(c => c).ToList(); sw.Close();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值