Http://u.115.com/file/f223235faf demo
Demo highlights
In the previous demonstration, we used two one-to-multiple relationships to establish pseudo-many-to-many relationships in LINQ to SQL. This is called a pseudo relationship, it indicates that it is not a true multi-to-many relationship. However, the previous practice has brought a little trouble to the caller who uses the object model. This is because the caller must display a cross-object when obtaining the data associated with the other party from either of the two object classes. Isn't that troublesome? In this demonstration, the effect we want to achieve is to hide the Object Class Object of the chain table.
The specific effect is as follows: Get the object of another object class associated with it directly through a collection attribute of the object class. Of course, this scheme is still based on the previous scheme, but we have to find a way to hide the chain table entity class.
In this demonstration, the final implementation result is as follows: Through customer. the products attribute directly obtains the data of all products ordered by the customer. MERs attribute to obtain all customer data for the current product.
No object model before modification
The following code is the object model before the modification, that is, the object model created in the previous demonstration, only the key code is pasted. The complete code has been packaged with the Demo Video, you can download and view.
Customer. CS
[Table(Name = "Customers")]public class Customer{ [Column(Name = "CustomerID", IsPrimaryKey = true)] public string CustomerID; private EntitySet<CustomerProduct> _CustomerProducts; [Association(Storage = "_CustomerProducts", ThisKey = "CustomerID", OtherKey = "CustomerID")] public EntitySet<CustomerProduct> CustomerProducts { get { return this._CustomerProducts; } set { this._CustomerProducts.Assign(value); } }}
Product. CS
Customerproduct. CS
[Table(Name = "CustomersProducts")]public class CustomerProduct{ private EntityRef<Customer> _Customer; [Association(Storage = "_Customer", ThisKey = "CustomerID", OtherKey = "CustomerID")] public Customer Customer { get { return this._Customer.Entity; } set { this._Customer.Entity = value; } } private EntityRef<Product> _Product; [Association(Storage = "_Product", ThisKey = "ProductID", OtherKey = "ProductID")] public Product Product { get { return this._Product.Entity; } set { this._Product.Entity = value; } }}
From the sample code above, the customer entity class does not have the products attribute, and the product entity class does not have the MERs attribute. It is not defined as it has not been pasted. How to define it? See the following two sections of code:
Customer. Products
[Table (name = "MERs")] public class customer {private entityset <product> _ products; // <summary> // obtain all product objects ordered by the current customer. /// </Summary> Public entityset <product> Products {get {If (this. _ products = NULL) This. _ products = new entityset <product> (); else this. _ products. clear (); foreach (VAR cpobject in this. customerproducts) {var productobject = cpobject. product; this. _ products. add (productobject);} return this. _ products ;}}}
Product. MERs
[Table (name = "Products")] public class product {private entityset <customer> _ MERs MERS; // <summary> /// obtain all the customer objects of the current product. /// </Summary> Public entityset <customer> MERs {get {If (this. _ MERs = NULL) This. _ MERs = new entityset <customer> (); else this. _ MERs. clear (); foreach (VAR cpobject in this. productcustomers) {var customerobject = cpobject. customer; this. _ MERs. add (customerobject);} return this. _ MERs ;}}}
Add the above two attributes to the corresponding object class. What do these codes mean? You should understand it at a glance. If you do not understand it, the Demo Video provides a detailed explanation.
With the above two attributes, you can use the customer. the products attribute directly accesses all the product objects ordered by the customer, or you can directly use the product. the customers attribute directly obtains all the customer objects that have subscribed to this product. In fact, we still use the chain-connected table entity class customerproduct, but we only hide this information in the set attribute.
Then, it is much easier for the caller to use this object model. The test code is as follows:
Obtain all the product objects ordered by the customer through the customer object:
**************************************** * ******* Obtain all the product objects ordered by the customer through the customer object. **************************************** * ******** Databasedatacontext DB = new databasedatacontext (@ "C: \ LINQ \ database. MDF "); var allcustomers = from customerobject in dB. customers select customerobject; foreach (VAR customerobject in allcustomers) {console. writeline ("----------------------------------------"); console. foregroundcolor = consolecolor. green; console. writeline ("Customer ID: {0}", customerobject. customerid); console. foregroundcolor = consolecolor. white; console. writeline ("customer name: {0}", customerobject. contactname); thread. sleep (1000); foreach (VAR productobject in mermerobject. products) {console. writeline ("productid = {0}, productname = {1}", productobject. productid, productobject. productname);} console. writeline (); thread. sleep (2000 );}
Obtain all customers who have subscribed to this product through the product object:
//************************************** * ********** // Obtain all the customers who have subscribed to this product through the product object directly. //************************************** * ********** Databasedatacontext DB = new databasedatacontext (@ "C: \ LINQ \ database. MDF "); var allproducts = from productobject in dB. products select productobject; foreach (VAR productobject in allproducts) {console. writeline ("----------------------------------------"); console. foregroundcolor = consolecolor. green; console. writeline ("Product ID: {0}", productobject. productid); console. foregroundcolor = consolecolor. white; console. writeline ("Product Name: {0}", productobject. productname); thread. sleep (1000); foreach (VAR customerobject in productobject. customers) {console. writeline ("customerid = {0}, contactname = {1}", customerobject. customerid, customerobject. contactname);} console. writeline (); thread. sleep (2000 );}
Oh, how is it? Is it simpler? Although the object model adds a little complexity, it becomes simpler when the caller calls this object model. Therefore, it is worthwhile to add this complexity to the object model, because sometimes we are the caller. What's more, the number of times the object model is used is far greater than the number of times the object model is defined! Pai_^
Barefoot thinking
[Table(Name = "Products")]public class Product{ private EntitySet<CustomerProduct> _ProductCustomers; [Association(Storage = "_ProductCustomers", ThisKey = "ProductID", OtherKey = "ProductID")] public EntitySet<CustomerProduct> ProductCustomers { get { return this._ProductCustomers; } set { this._ProductCustomers.Assign(value); } }}