• 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();
    6, 更新时的冲突和事务
    紫色阴影写的挺好的。引他的吧。
    http://www.cnblogs.com/blusehuang/archive/2007/07/16/819677.html 事务
    http://www.cnblogs.com/blusehuang/archive/2007/07/06/808529.html  冲突

    PS:关于成立linq团队的提议。有人响应没?把我做为一个创始人就是了。^_^

    TrackBack:http://www.cnblogs.com/126/archive/2007/08/08/848200.html

  • 相关阅读:
    ZOJ 2604 Little Brackets DP
    js实现回放拖拽轨迹-------Day48
    Android蓝牙开发
    linux中的两个很重要的信号:SIGALRM信号和SIGCHID信号
    MySQL mysqldump数据导出详解
    JFinal redis cluster集群插件
    nginx平滑升级
    温故而知新-String类
    Linux环境变量具体解释
    android消息机制
  • 原文地址:https://www.cnblogs.com/hdjjun/p/1327118.html
Copyright © 2020-2023  润新知