2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / System.Data.Linq / src / DbLinq / Test / Providers / ReadTests_Join.cs
1 #region MIT license\r
2 // \r
3 // MIT license\r
4 //\r
5 // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne\r
6 // \r
7 // Permission is hereby granted, free of charge, to any person obtaining a copy\r
8 // of this software and associated documentation files (the "Software"), to deal\r
9 // in the Software without restriction, including without limitation the rights\r
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
11 // copies of the Software, and to permit persons to whom the Software is\r
12 // furnished to do so, subject to the following conditions:\r
13 // \r
14 // The above copyright notice and this permission notice shall be included in\r
15 // all copies or substantial portions of the Software.\r
16 // \r
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
23 // THE SOFTWARE.\r
24 // \r
25 #endregion\r
26 using System;\r
27 using System.Globalization;\r
28 using System.Collections.Generic;\r
29 using System.Text;\r
30 using System.Linq;\r
31 using System.Linq.Expressions;\r
32 using NUnit.Framework;\r
33 using Test_NUnit;\r
34 \r
35 using nwind;\r
36 \r
37 #if MONO_STRICT\r
38 using System.Data.Linq;\r
39 #else\r
40 using DbLinq.Data.Linq;\r
41 #endif\r
42 \r
43 // test ns \r
44 #if MYSQL\r
45     namespace Test_NUnit_MySql\r
46 #elif ORACLE && ODP\r
47     namespace Test_NUnit_OracleODP\r
48 #elif ORACLE\r
49     namespace Test_NUnit_Oracle\r
50 #elif POSTGRES\r
51     namespace Test_NUnit_PostgreSql\r
52 #elif SQLITE\r
53     namespace Test_NUnit_Sqlite\r
54 #elif INGRES\r
55     namespace Test_NUnit_Ingres\r
56 #elif MSSQL && L2SQL\r
57     namespace Test_NUnit_MsSql_Strict\r
58 #elif MSSQL\r
59     namespace Test_NUnit_MsSql\r
60 #elif FIREBIRD\r
61     namespace Test_NUnit_Firebird\r
62 #endif\r
63 {\r
64     [TestFixture]\r
65     public class ReadTests_Join : TestBase\r
66     {\r
67 \r
68 #if !DEBUG && (SQLITE || (MSSQL && !L2SQL))\r
69         [Explicit]\r
70 #endif\r
71         [Test(Description = "example by Frans Brouma: select all customers that have no orders")]\r
72         public void LeftJoin_DefaultIfEmpty()\r
73         {\r
74             //example by Frans Brouma on Matt Warren's site\r
75             //select all customers that have no orders\r
76             //http://blogs.msdn.com/mattwar/archive/2007/09/04/linq-building-an-iqueryable-provider-part-vii.aspx\r
77             //http://weblogs.asp.net/fbouma/archive/2007/11/23/developing-linq-to-llblgen-pro-part-9.aspx\r
78 \r
79             Northwind db = CreateDB();\r
80 \r
81             var q = from c in db.Customers\r
82                     join o in db.Orders on c.CustomerID equals o.CustomerID into oc\r
83                     from x in oc.DefaultIfEmpty()\r
84                     where x.OrderID == null\r
85                     select c;\r
86 \r
87             var list = q.ToList();\r
88             Assert.IsTrue(list.Count > 0);\r
89             int countPARIS = list.Count(item => item.CustomerID == "PARIS");\r
90             Assert.IsTrue(countPARIS == 1);\r
91         }\r
92 \r
93         [Test]\r
94         public void LeftOuterJoin_Suppliers()\r
95         {\r
96             //http://blogs.class-a.nl/blogs/anko/archive/2008/03/14/linq-to-sql-outer-joins.aspx\r
97             //example by Anko Duizer (NL)\r
98             Northwind db = CreateDB();\r
99             var query = from s in db.Suppliers\r
100                         join c in db.Customers on s.City equals c.City into temp\r
101                         from t in temp.DefaultIfEmpty()\r
102                         select new\r
103                         {\r
104                             SupplierName = s.CompanyName,\r
105                             CustomerName = t.CompanyName,\r
106                             City = s.City\r
107                         };\r
108 \r
109             var list = query.ToList();\r
110 \r
111             bool foundMelb = false, foundNull = false;\r
112             foreach (var item in list)\r
113             {\r
114                 foundMelb = foundMelb || item.City == "Melbourne";\r
115                 foundNull = foundNull || item.City == null;\r
116             }\r
117             Assert.IsTrue(foundMelb, "Expected rows with City=Melbourne");\r
118             Assert.IsFalse(foundNull, "Expected no rows with City=null");\r
119         }\r
120 \r
121         // picrap: commented out, it doesn't build because of db.Orderdetails (again, a shared source file...)\r
122 \r
123         [Test(Description = "Problem discovered by Laurent")]\r
124         public void Join_Laurent()\r
125         {\r
126             Northwind db = CreateDB();\r
127 \r
128             var q1 = (from p in db.Products\r
129                       join o in db.OrderDetails on p.ProductID equals o.ProductID\r
130                       where p.ProductID > 1\r
131                       select new\r
132                       {\r
133                           p.ProductName,\r
134                           o.OrderID,\r
135                           o.ProductID,\r
136                       }\r
137                       ).ToList();\r
138 \r
139             Assert.IsTrue(q1.Count > 0);\r
140         }\r
141 \r
142 #if !DEBUG && (SQLITE || MSSQL)\r
143         // L2SQL: System.InvalidOperationException : The type 'Test_NUnit_MsSql_Strict.ReadTests_Join+Northwind1+ExtendedOrder' is not mapped as a Table.\r
144         [Explicit]\r
145 #endif\r
146         [Test]\r
147         public void RetrieveParentAssociationProperty()\r
148         {\r
149             Northwind dbo = CreateDB();\r
150             Northwind1 db = new Northwind1(dbo.Connection);\r
151             var t = db.GetTable<Northwind1.ExtendedOrder>();\r
152             var q = from order in t\r
153                     select new\r
154                     {\r
155                         order.OrderID,\r
156                         order.CustomerShipCity.ContactName\r
157                     };\r
158             var list = q.ToList();\r
159             Assert.IsTrue(list.Count > 0);\r
160         }\r
161 \r
162 \r
163 \r
164 #if !DEBUG && (SQLITE || MSSQL)\r
165         // L2SQL: System.InvalidOperationException : The type 'Test_NUnit_MsSql_Strict.ReadTests_Join+Northwind1+ExtendedOrder' is not mapped as a Table.\r
166         [Explicit]\r
167 #endif\r
168         [Test]\r
169         public void DifferentParentAndAssociationPropertyNames()\r
170         {\r
171             Northwind dbo = CreateDB();\r
172             Northwind1 db = new Northwind1(dbo.Connection);\r
173             var query = db.GetTable<Northwind1.ExtendedOrder>() as IQueryable<Northwind1.ExtendedOrder>;\r
174 \r
175             var q2 = query.Select(e => new Northwind1.ExtendedOrder\r
176             {\r
177                 OrderID = e.OrderID,\r
178                 ShipAddress = e.CustomerShipCity.ContactName\r
179             });\r
180             var list = q2.ToList();\r
181             Assert.IsTrue(list.Count > 0);\r
182         }\r
183 \r
184 #if !DEBUG && (SQLITE || MSSQL)\r
185         // L2SQL: System.InvalidOperationException : The type 'Test_NUnit_MsSql_Strict.ReadTests_Join+Northwind1+ExtendedOrder' is not mapped as a Table.\r
186         [Explicit]\r
187 #endif\r
188         [Test]\r
189         public void SelectCustomerContactNameFromOrder()\r
190         {\r
191             Northwind dbo = CreateDB();\r
192             Northwind1 db = new Northwind1(dbo.Connection);\r
193             var t = db.GetTable<Northwind1.ExtendedOrder>();\r
194 \r
195             var q = from order in t\r
196                     select new\r
197                     {\r
198                         order.CustomerContactName\r
199                     };\r
200             var list = q.ToList();\r
201             Assert.AreEqual(db.Orders.Count(), list.Count());\r
202             foreach (var s in list)\r
203                 Assert.AreEqual("Test", s);\r
204         }\r
205 \r
206         public class Northwind1 : Northwind\r
207         {\r
208             public Northwind1(System.Data.IDbConnection connection)\r
209                 : base(connection) { }\r
210 \r
211             // Linq-SQL requires this: [System.Data.Linq.Mapping.Table(Name = "orders")]\r
212             public class ExtendedOrder : Order\r
213             {\r
214 #if MONO_STRICT\r
215                 System.Data.Linq\r
216 #else\r
217                 DbLinq.Data.Linq\r
218 #endif\r
219 .EntityRef<Customer> _x_Customer;\r
220 \r
221                 [System.Data.Linq.Mapping.Association(Storage = "_x_Customer",\r
222                     ThisKey = "ShipCity", Name =\r
223 #if MYSQL\r
224  "orders_ibfk_1"\r
225 #elif ORACLE\r
226  "SYS_C004742"\r
227 #elif POSTGRES\r
228  "fk_order_customer"\r
229 #elif SQLITE\r
230  "fk_Orders_1"\r
231 #elif INGRES\r
232  "fk_order_customer"\r
233 #elif MSSQL\r
234  "fk_order_customer"\r
235 #elif FIREBIRD\r
236  "??" // TODO: correct FK name\r
237 #else\r
238 #error unknown target\r
239 #endif\r
240 )]\r
241                 public Customer CustomerShipCity\r
242                 {\r
243                     get { return _x_Customer.Entity; }\r
244                     set { _x_Customer.Entity = value; }\r
245                 }\r
246 \r
247                 public string CustomerContactName\r
248                 {\r
249                     get\r
250                     {\r
251                         return "Test";\r
252                     }\r
253                 }\r
254             }\r
255 \r
256             public Table<ExtendedOrder> ExtendedOrders\r
257             {\r
258                 get { return base.GetTable<ExtendedOrder>(); }\r
259             }\r
260         }\r
261 \r
262         [Test]\r
263         [ExpectedException(typeof(NotSupportedException))]\r
264         public void WhereBeforeSelect()\r
265         {\r
266             Northwind db = CreateDB();\r
267             var t = db.GetTable<Order>();\r
268 \r
269             var query = t.Where(o => o.OrderID != 0);\r
270 \r
271             query = query.Select(dok => new Order\r
272             {\r
273                 OrderID = dok.OrderID,\r
274                 OrderDate = dok.OrderDate,\r
275                 ShipCity = dok.Customer.ContactName,\r
276                 Freight = dok.Freight\r
277             });\r
278             var list = query.ToList();\r
279         }\r
280 \r
281         /// <summary>\r
282         /// Reported by  pwy.mail in http://code.google.com/p/dblinq2007/issues/detail?id=66\r
283         /// </summary>\r
284         [Test]\r
285         public void OrdersLazyLoad()\r
286         {\r
287             Northwind db = CreateDB();\r
288 \r
289             var q =\r
290               from c in db.Customers\r
291               select c;\r
292 \r
293             foreach (var c in q)\r
294             {\r
295                 Console.WriteLine(c.Address);\r
296                 foreach (var o in c.Orders)\r
297                     Console.WriteLine(o.OrderID);\r
298             }\r
299 \r
300         }\r
301 \r
302         [Test]\r
303         public void JoinWhere()\r
304         {\r
305             Northwind db = CreateDB();\r
306 \r
307             var custID = "BT___";\r
308 \r
309             var custOderInfos = from o in db.Orders\r
310                                 join em in db.Employees on o.EmployeeID equals em.EmployeeID\r
311                                 where o.CustomerID == custID\r
312                                 select new { o, em };\r
313 \r
314             var l = custOderInfos.ToList();\r
315         }\r
316 \r
317 #if !DEBUG && (SQLITE || (MSSQL && !L2SQL))\r
318         [Explicit]\r
319 #endif\r
320         [Test]\r
321         // submitted by bryan costanich\r
322         public void ImplicitLeftOuterJoin()\r
323         {\r
324             var db = CreateDB();\r
325 \r
326             var dbItems =\r
327                     (from a in db.Products\r
328                      from b in db.Suppliers\r
329                      where a.SupplierID == b.SupplierID\r
330                      select a);\r
331 \r
332             var list = dbItems.ToList();\r
333         }\r
334     }\r
335 \r
336 }\r