Linq To Sql進階系列(三)CUD和Log

來源:互聯網
上載者:User

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團隊的提議。有人響應沒?把我做為一個創始人就是了。^_^

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.