├── source
├── 01-GetStarted
│ └── SeeVisualStudioProject.txt
├── Assets
│ └── ExeEF
│ │ ├── Tours.mdf
│ │ ├── Tours_log.ldf
│ │ ├── ConsoleForEF.exe
│ │ ├── ConsoleForEF.pdb
│ │ ├── NorthwindV13.MDF
│ │ ├── EntityFramework.dll
│ │ ├── NorthwindV13_log.ldf
│ │ ├── EntityFramework.SqlServer.dll
│ │ └── ConsoleForEF.exe.config
├── VisualStudio
│ ├── ConsoleForEF
│ │ ├── Diagrams
│ │ │ ├── ToursDiagram.cd
│ │ │ └── LinqTypesDiagram.cd
│ │ ├── Tours.mdf
│ │ ├── Tours_log.ldf
│ │ ├── NorthwindV13.MDF
│ │ ├── NorthwindV13_log.ldf
│ │ ├── packages.config
│ │ ├── ToursModel.cs
│ │ ├── NorthwindModel.cs
│ │ ├── TravelTip.cs
│ │ ├── Testimonial.cs
│ │ ├── ToursModel.Designer.cs
│ │ ├── NorthwindModel.Designer.cs
│ │ ├── ToursModel.edmx.diagram
│ │ ├── Program.cs
│ │ ├── Order_Detail.cs
│ │ ├── Tour.cs
│ │ ├── ToursModel.Context.cs
│ │ ├── Region.cs
│ │ ├── Shipper.cs
│ │ ├── Category.cs
│ │ ├── Territory.cs
│ │ ├── Contact.cs
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ ├── Customer.cs
│ │ ├── Supplier.cs
│ │ ├── NorthwindModel.Context.cs
│ │ ├── Product.cs
│ │ ├── App.config
│ │ ├── Order.cs
│ │ ├── Employee.cs
│ │ ├── NorthwindModel.edmx.diagram
│ │ ├── ToursModel.edmx
│ │ ├── ConsoleForEF.csproj
│ │ ├── ToursModel.Context.tt
│ │ ├── NorthwindModel.Context.tt
│ │ └── ToursModel.tt
│ └── LinqForDB.sln
├── 02-DB and LINQPad
│ ├── 03-Connect To Entity Framework.linq
│ ├── 04-View DB structure in UI.linq
│ ├── 01-The included sample connection.linq
│ └── 02-Connect To Another DB.linq
├── 04-Basic Syntax
│ ├── 01-Documentation Links.linq
│ ├── 01-Query Basics.linq
│ ├── 01-Operator List.linq
│ ├── 03B-Extension methods.linq
│ ├── 03C-Extension methods.linq
│ ├── 02-Enumerable vs Queryable methods.linq
│ ├── 03A-Extension methods.linq
│ ├── 04C-Query Expression.linq
│ ├── 04A-Query Expression.linq
│ ├── 04D-Query Expression.linq
│ └── 04B-Query Expression.linq
├── 03-Queryable
│ ├── 09B-View SQL.linq
│ ├── 09A-View SQL.linq
│ ├── 08-ExpressionTree.linq
│ ├── 07A-Interfaces.linq
│ ├── 06A-DbQuery.linq
│ ├── 05A-DbSet Add.linq
│ ├── 04-DbSet.linq
│ ├── 05B-DbSet Remove.linq
│ ├── 02-DbContext.linq
│ └── 07B-Interfaces.linq
├── OtherExamples
│ ├── View Connection Info.linq
│ ├── 04-Connection.linq
│ ├── 02-SQL.linq
│ └── 05-Dataset.linq
└── 05-Query Examples
│ ├── 04B-Joins.linq
│ ├── 04A-Joins.linq
│ ├── 07-Flatten with SelectMany.linq
│ ├── 06B-Group.linq
│ ├── 05-Contains.linq
│ ├── 06A-Group.linq
│ ├── 01B-Use projection to get less data.linq
│ ├── 03-Where and Find.linq
│ ├── 01A-Use projection to get less data.linq
│ ├── 08-DateRange.linq
│ └── 02-Use Take, Skip to page data.linq
├── .github
├── CODEOWNERS
├── PULL_REQUEST_TEMPLATE.md
└── ISSUE_TEMPLATE.md
├── CONTRIBUTING.md
├── NOTICE
├── README.md
├── LICENSE
└── .gitignore
/source/01-GetStarted/SeeVisualStudioProject.txt:
--------------------------------------------------------------------------------
1 | Examples are in the Visual Studio folder
--------------------------------------------------------------------------------
/source/Assets/ExeEF/Tours.mdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/Assets/ExeEF/Tours.mdf
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Diagrams/ToursDiagram.cd:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/source/Assets/ExeEF/Tours_log.ldf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/Assets/ExeEF/Tours_log.ldf
--------------------------------------------------------------------------------
/source/Assets/ExeEF/ConsoleForEF.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/Assets/ExeEF/ConsoleForEF.exe
--------------------------------------------------------------------------------
/source/Assets/ExeEF/ConsoleForEF.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/Assets/ExeEF/ConsoleForEF.pdb
--------------------------------------------------------------------------------
/source/Assets/ExeEF/NorthwindV13.MDF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/Assets/ExeEF/NorthwindV13.MDF
--------------------------------------------------------------------------------
/source/Assets/ExeEF/EntityFramework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/Assets/ExeEF/EntityFramework.dll
--------------------------------------------------------------------------------
/source/Assets/ExeEF/NorthwindV13_log.ldf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/Assets/ExeEF/NorthwindV13_log.ldf
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Tours.mdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/VisualStudio/ConsoleForEF/Tours.mdf
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Tours_log.ldf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/VisualStudio/ConsoleForEF/Tours_log.ldf
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Codeowners for these exercise files:
2 | # * (asterisk) deotes "all files and folders"
3 | # Example: * @producer @instructor
4 |
--------------------------------------------------------------------------------
/source/Assets/ExeEF/EntityFramework.SqlServer.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/Assets/ExeEF/EntityFramework.SqlServer.dll
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/NorthwindV13.MDF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/VisualStudio/ConsoleForEF/NorthwindV13.MDF
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/NorthwindV13_log.ldf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/linq-to-db/HEAD/source/VisualStudio/ConsoleForEF/NorthwindV13_log.ldf
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/source/02-DB and LINQPad/03-Connect To Entity Framework.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | // An Entity Framework source is comprised of .NET mapping classes
4 | // Connections to EF classes in LINQPad are done by using the .NET exe or dll that contains the types
5 |
6 |
7 | // for this course, we'll use the ConsoleForEF.exe executable.
--------------------------------------------------------------------------------
/source/04-Basic Syntax/01-Documentation Links.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | // Read more about Query Operators at Microsoft docs.
4 |
5 | // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/query-expression-syntax-for-standard-query-operators
6 |
7 | // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/standard-query-operators-overview
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/ToursModel.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/NorthwindModel.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 |
--------------------------------------------------------------------------------
/source/02-DB and LINQPad/04-View DB structure in UI.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | 54bf9502-9daf-4093-88e8-7177c129999f
4 | 2
5 | System.Data.SqlServerCe.4.0
6 | <ApplicationData>\LINQPad\DemoDB.sdf
7 | true
8 | true
9 |
10 |
11 |
12 | // View the DB tables
13 | // and Entity Framework types in the Connection pane on left
--------------------------------------------------------------------------------
/source/04-Basic Syntax/01-Query Basics.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | // LINQ query operators are implemented as Extension methods...
4 |
5 | // Call via the 'method syntax', pass in lambda expressions as parameters
6 | // Use Linq Query Expression
7 |
8 | // source.Where (predicateExpression);
9 |
10 | // Or use the LINQ query expression syntax
11 |
12 | // from s in source
13 | // where predicateExpression
14 | // select s;
15 |
16 | // Calls via the 'query syntax',
17 | // are converted to method syntax
18 |
19 |
20 | // Learn more about LINQ
21 | // https://www.linkedin.com/learning/topics/linq
22 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 | Contribution Agreement
3 | ======================
4 |
5 | This repository does not accept pull requests (PRs). All pull requests will be closed.
6 |
7 | However, if any contributions (through pull requests, issues, feedback or otherwise) are provided, as a contributor, you represent that the code you submit is your original work or that of your employer (in which case you represent you have the right to bind your employer). By submitting code (or otherwise providing feedback), you (and, if applicable, your employer) are licensing the submitted code (and/or feedback) to LinkedIn and the open source community subject to the BSD 2-Clause license.
8 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | Copyright 2021 LinkedIn Corporation
2 | All Rights Reserved.
3 |
4 | Licensed under the LinkedIn Learning Exercise File License (the "License").
5 | See LICENSE in the project root for license information.
6 |
7 | Please note, this project may automatically load third party code from external
8 | repositories (for example, NPM modules, Composer packages, or other dependencies).
9 | If so, such third party code may be subject to other license terms than as set
10 | forth above. In addition, such third party code may also depend on and load
11 | multiple tiers of dependencies. Please review the applicable licenses of the
12 | additional dependencies.
13 |
--------------------------------------------------------------------------------
/source/02-DB and LINQPad/01-The included sample connection.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | // LINQPad includes a sample SQLCE (Compact Edition) database
4 |
5 | // It's installed at C:\Users[current user]\AppData\Roaming\LINQPad
6 | // It's added as a sample database connection in the connection panel (on left).
7 |
8 | // The database (DemoDB.sdf) requires SQL CE. The first time you expand the connection,
9 | // LINQPad will ask if want to download the NuGet package for SQL CE
10 | // if the package is not in the Visual Studio NuGet cache.
11 |
12 |
13 | // LINQPad 6 targets .NET Core 3 and .NET 5 for Windows.
14 | // LINQPad 5 Targets .NET Framework
--------------------------------------------------------------------------------
/source/03-Queryable/09B-View SQL.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 |
11 |
12 | Shippers.Dump();
13 |
14 | var q1 = from s in Shippers
15 | select s;
16 |
17 | q1.Dump();
--------------------------------------------------------------------------------
/source/04-Basic Syntax/01-Operator List.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | // Lots of Extension methods, similar to what is available for LINQ to Objects
4 |
5 | // [Basics]
6 | // Select, Where, Orderby
7 |
8 | // [Aggregates]
9 | // Sum, Average, Count, Min, Max
10 |
11 | // [Sets]
12 | // Union, Intersect, Distinct, Except
13 |
14 | // [Quantifiers]
15 | // All, Any, Contains
16 |
17 | // [Partitions]
18 | // Skip, Take, SkipWhile, TakeWhile
19 |
20 | // [Groups]
21 | // GroupBy, ToLookup
22 |
23 | // [Elements]
24 | // First, Last, ElementAt, Single, FirstOrDefault...
25 |
26 | // [Joins]
27 | // Join, GroupJoin
28 |
29 | // Learn more about LINQ
30 | // https://www.linkedin.com/learning/topics/linq
31 |
--------------------------------------------------------------------------------
/source/02-DB and LINQPad/02-Connect To Another DB.linq:
--------------------------------------------------------------------------------
1 |
2 | System.Numerics
3 |
4 |
5 | // add connections to
6 | // SQL Server, SQL Azure, SQL CE, Oracle, SQLite, PostgreSQL and MySQL
7 | // Azure Table Storage & Azure Metadata
8 | // Entity Framework Core custom contexts
9 | // Microsoft Reactive Extensions and LINQ to Logs & Traces
10 | // OData and SharePoint
11 | // Third - party ORMs: Mindscape LightSpeed, DevArt’s LinqConnect, LLBLGen,
12 | // DevExpress eXpress Persistent Objects and DevForce
13 |
14 |
15 |
16 | // LINQPad 6 targets .NET Core 3 and .NET 5 for Windows.
17 | // LINQPad 5 Targets .NET Framework
18 |
19 | // Connect to (localdb)\MSSQLLocalDB
20 | //
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/TravelTip.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class TravelTip
16 | {
17 | public int TipId { get; set; }
18 | public string Headline { get; set; }
19 | public string TipText { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/source/03-Queryable/09A-View SQL.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 |
11 |
12 | // Use the SQL property to get the SQL used for the query
13 |
14 | Categories.Sql.Dump();
15 | Categories.ToString().Dump(); // ToString works too!
16 |
17 | var q1 = from s in Shippers
18 | select s;
19 | q1.ToString().Dump();
20 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Testimonial.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Testimonial
16 | {
17 | public int TestimonialId { get; set; }
18 | public string CustomerName { get; set; }
19 | public string Comment { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/source/04-Basic Syntax/03B-Extension methods.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 |
11 |
12 | // Extension methods
13 |
14 | // Pipeline the extension methods.
15 |
16 | var orderedResults = Products.OrderBy(p => p.ProductName);
17 |
18 | var pipelinedResults = orderedResults.Where(p => p.UnitsInStock == 0);
19 |
20 |
21 | pipelinedResults.Dump();
--------------------------------------------------------------------------------
/source/04-Basic Syntax/03C-Extension methods.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 |
11 |
12 | // Extension methods
13 |
14 | // Pipeline the extension methods.
15 |
16 | var pipelinedResults = Products.OrderBy(p => p.UnitPrice )
17 | .Where(p => p.UnitsInStock ==0 )
18 | .Select(p => p.ProductName);
19 |
20 | pipelinedResults.Dump();
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/ToursModel.Designer.cs:
--------------------------------------------------------------------------------
1 | // T4 code generation is enabled for model 'C:\Users\WR\Source\Repos\linq-databases-2858036\source\VisualStudio\ConsoleForEF\ToursModel.edmx'.
2 | // To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
3 | // property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
4 | // is open in the designer.
5 |
6 | // If no context and entity classes have been generated, it may be because you created an empty model but
7 | // have not yet chosen which version of Entity Framework to use. To generate a context class and entity
8 | // classes for your model, open the model in the designer, right-click on the designer surface, and
9 | // select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
10 | // Item...'.
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/NorthwindModel.Designer.cs:
--------------------------------------------------------------------------------
1 | // T4 code generation is enabled for model 'C:\Users\WR\Source\Repos\linq-databases-2858036\source\VisualStudio\ConsoleForEF\NorthwindModel.edmx'.
2 | // To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
3 | // property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
4 | // is open in the designer.
5 |
6 | // If no context and entity classes have been generated, it may be because you created an empty model but
7 | // have not yet chosen which version of Entity Framework to use. To generate a context class and entity
8 | // classes for your model, open the model in the designer, right-click on the designer surface, and
9 | // select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
10 | // Item...'.
--------------------------------------------------------------------------------
/source/OtherExamples/View Connection Info.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | 54bf9502-9daf-4093-88e8-7177c129999f
4 | 2
5 | System.Data.SqlServerCe.4.0
6 | <ApplicationData>\LINQPad\DemoDB.sdf
7 | true
8 | true
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var ctx = this;
14 |
15 | //ctx.Dump();
16 | ctx.Shippers.GetType().FullName.Dump();
17 | ctx.Connection.Open();
18 | ctx.Connection.Dump();
19 | ctx.GetType().BaseType.BaseType.BaseType.Dump();
20 | ctx.Connection.Close();
--------------------------------------------------------------------------------
/source/04-Basic Syntax/02-Enumerable vs Queryable methods.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 |
11 |
12 | var colors = new List
13 | { "Green", "Blush", "Yellow", "Red", "Orange",
14 | "Burgandy", "Purple", "White", "Black", "Blue" ,"Bronze"};
15 |
16 | var q1 = colors.Where(c => c.StartsWith("B") );
17 | q1.Dump();
18 |
19 | var q2 = Products.Where(p => p.ProductName.StartsWith("F"));
20 | q2.Dump();
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/ToursModel.edmx.diagram:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ConsoleForEF
8 | {
9 | class Program
10 | {
11 | static void Main(string[] args)
12 | {
13 | // get the Entity Framework (EF) data context
14 | // using the default connection defined in the app.config file
15 | var context = new NorthwindEntities();
16 |
17 | // work with the EF model classes
18 |
19 | var shipper = context.Shippers.First();
20 |
21 | Console.WriteLine(shipper.CompanyName);
22 |
23 | //var products = from p in context.Products
24 | // where p.UnitPrice < 20
25 | // select new { p.ProductName, p.UnitPrice };
26 |
27 | //foreach (var product in products)
28 | //{
29 | // Console.WriteLine($"{product.ProductName}, {product.UnitPrice} ");
30 | //}
31 |
32 |
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/source/04-Basic Syntax/03A-Extension methods.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 |
11 |
12 | // Extension methods
13 |
14 | // Call a single extension method
15 |
16 | var orderedResults = Products.OrderBy(p => p.ProductName);
17 |
18 | var filteredResults = Products.Where(p => p.UnitsInStock == 0);
19 |
20 | orderedResults.Dump();
21 | filteredResults.Dump();
22 |
23 | // Learn more about LINQ
24 | // https://www.linkedin.com/learning/topics/linq
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Order_Detail.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Order_Detail
16 | {
17 | public int OrderID { get; set; }
18 | public int ProductID { get; set; }
19 | public decimal UnitPrice { get; set; }
20 | public short Quantity { get; set; }
21 | public float Discount { get; set; }
22 |
23 | public virtual Order Order { get; set; }
24 | public virtual Product Product { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/source/05-Query Examples/04B-Joins.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | System.Data.Entity
11 |
12 |
13 | // The DB joins are defined in the EF mapping
14 | // this simplifies common queries.
15 |
16 |
17 |
18 | var q2 = from o in Order_Details
19 | where o.Order.CustomerID == "ISLAT"
20 | select new {o.Order.Customer.CompanyName, o.Order.OrderDate,
21 | o.Product.ProductName, Employee= o.Order.Employee.FirstName + " " + o.Order.Employee.LastName };
22 |
23 | q2.Take (10).Dump();
--------------------------------------------------------------------------------
/source/OtherExamples/04-Connection.linq:
--------------------------------------------------------------------------------
1 |
2 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\DB\System.Data.SqlServerCe.dll
3 | System.Data.SqlClient
4 | System.Numerics
5 |
6 |
7 | // LINQPad provides an easy way to get data context for a database
8 | // this example bypasses the LINQPad system and uses basic ADO.NET
9 | // Note: since this is .NET core
10 | // add System.Data.Common and System.Data.SqlClient nuget packages.
11 | void Main()
12 | {
13 | var ds = new DataSet();
14 | OpenDBConnection();
15 | }
16 |
17 | // You can define other methods, fields, classes and namespaces here
18 | void OpenDBConnection()
19 | {
20 |
21 |
22 | string cnString = @"data source='C:\Users\WR\AppData\Roaming\LINQPad\DemoDB.sdf'";
23 |
24 | using (var conn = new System.Data.SqlServerCe.SqlCeConnection(cnString))
25 | {
26 | conn.Open();
27 |
28 | conn.Dump();
29 | conn.Close();
30 |
31 | }
32 | }
--------------------------------------------------------------------------------
/source/05-Query Examples/04A-Joins.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 |
11 |
12 | // The DB joins are defined in the EF mapping
13 | // In the entity classes they are represented as Navigation properties.
14 | // Navigation properties provide a way to navigate an association between two entity types
15 | // They allow you to navigate and manage relationships in both directions
16 |
17 | // this simplifies common LINQ queries.
18 |
19 |
20 |
21 | var q2 = from o in Order_Details
22 | where o.Order.CustomerID =="ISLAT"
23 | select o;
24 |
25 | q2.Dump();
--------------------------------------------------------------------------------
/source/03-Queryable/08-ExpressionTree.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var context = new NorthwindEntities();
14 |
15 | var q1 = from r in context.Regions
16 | where r.RegionID == 2
17 | select r;
18 |
19 | q1.Dump();
20 |
21 | // View the query provider.
22 | q1.Provider.ToString().Dump();
23 | // View the expression tree
24 |
25 | q1.Expression.Dump();
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Tour.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Tour
16 | {
17 | public int TourId { get; set; }
18 | public string TourName { get; set; }
19 | public Nullable SeniorDiscountAvailable { get; set; }
20 | public Nullable KidFriendly { get; set; }
21 | public Nullable MultiDay { get; set; }
22 | public string Region { get; set; }
23 | public Nullable MaxPeoplePerTour { get; set; }
24 | public string TourImagePath { get; set; }
25 | public string Description { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/source/03-Queryable/07A-Interfaces.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var context = new NorthwindEntities();
14 | // Products is DbSet
15 | context.Products.GetType().Name.Dump("Products property is DbSet");
16 |
17 | // this query is DbQuery
18 | var q = from p in Products
19 | select p;
20 |
21 | q.GetType().Name.Dump("The query is DbQuery");
22 | Products.Select(p => p).GetType().Name.Dump("DbQuery from Extension method");
23 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
7 |
8 | ## Issue Overview
9 |
10 |
11 | ## Describe your environment
12 |
13 |
14 | ## Steps to Reproduce
15 |
16 | 1.
17 | 2.
18 | 3.
19 | 4.
20 |
21 | ## Expected Behavior
22 |
23 |
24 | ## Current Behavior
25 |
26 |
27 | ## Possible Solution
28 |
29 |
30 | ## Screenshots / Video
31 |
32 |
33 | ## Related Issues
34 |
35 |
--------------------------------------------------------------------------------
/source/04-Basic Syntax/04C-Query Expression.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // instead of pipelining, add clauses to query expression
14 | var manyClauses = from p in Products
15 | orderby p.UnitPrice
16 | where p.UnitsInStock == 0
17 | select p.ProductName;
18 |
19 |
20 |
21 | manyClauses.Dump();
22 |
23 |
24 |
25 |
26 | // Learn more about LINQ
27 | // https://www.linkedin.com/learning/topics/linq
--------------------------------------------------------------------------------
/source/05-Query Examples/07-Flatten with SelectMany.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | c54576d1-888b-4050-976b-0c662e22b616
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // SelectMany flattens a one-many relationship
14 | // or saying it another way , it can ungroup nested sequences
15 |
16 |
17 | Regions.Dump();
18 | var q1 = from r in Regions
19 | select r.Territories;
20 | q1.Dump("4 hashset collections in result");
21 | var q2 = Regions.SelectMany(r =>r.Territories);
22 |
23 | q2.Dump("Flattened to a single DbQuery");
--------------------------------------------------------------------------------
/source/04-Basic Syntax/04A-Query Expression.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // Query expression syntax
14 | // a pass through query, returns all rows and columns
15 | // same as SELECT * FROM TABLE_NAME in SQL
16 |
17 |
18 | var q1 = from s in Shippers
19 | select s;
20 | var q2 = from t in Territories
21 | select t;
22 | q1.Dump();
23 | q2.Dump();
24 |
25 |
26 |
27 | // Learn more about LINQ
28 | // https://www.linkedin.com/learning/topics/linq
--------------------------------------------------------------------------------
/source/05-Query Examples/06B-Group.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | c54576d1-888b-4050-976b-0c662e22b616
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // group by ship country
14 |
15 |
16 | var q = from o in Orders
17 | group o by o.ShipCountry into shipGroup
18 | select new { shipGroup.Key, Total = shipGroup.Sum(o => o.Freight) } into totalItem
19 | orderby totalItem.Total, totalItem.Key
20 | select new { TotalShipCost = totalItem.Total, Country = totalItem.Key };
21 |
22 | q.Dump("Orders grouped by ship country showing total:");
--------------------------------------------------------------------------------
/source/05-Query Examples/05-Contains.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 |
14 | // use results of a query as arguments to another query
15 |
16 |
17 | var q1 = from p in Products
18 | where p.UnitPrice > 90
19 | select p.ProductID;
20 |
21 | q1.Dump();
22 |
23 | Order_Details.Take(10).Dump();
24 |
25 | var productIds= q1.ToList();
26 | var q2 = from o in Order_Details
27 |
28 | where productIds.Contains(o.Product.ProductID)
29 | select o;
30 | q2.Dump();
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/ToursModel.Context.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Data.Entity;
14 | using System.Data.Entity.Infrastructure;
15 |
16 | public partial class ToursEntities : DbContext
17 | {
18 | public ToursEntities()
19 | : base("name=ToursEntities")
20 | {
21 | }
22 |
23 | protected override void OnModelCreating(DbModelBuilder modelBuilder)
24 | {
25 | throw new UnintentionalCodeFirstException();
26 | }
27 |
28 | public virtual DbSet Testimonials { get; set; }
29 | public virtual DbSet Tours { get; set; }
30 | public virtual DbSet TravelTips { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/source/VisualStudio/LinqForDB.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30413.136
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleForEF", "ConsoleForEF\ConsoleForEF.csproj", "{576E8704-2FFB-4211-9AE9-2CE09902ED87}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {576E8704-2FFB-4211-9AE9-2CE09902ED87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {576E8704-2FFB-4211-9AE9-2CE09902ED87}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {576E8704-2FFB-4211-9AE9-2CE09902ED87}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {576E8704-2FFB-4211-9AE9-2CE09902ED87}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {502DB44D-7775-46D8-97EE-C48C71138FC9}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Region.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Region
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Region()
19 | {
20 | this.Territories = new HashSet();
21 | }
22 |
23 | public int RegionID { get; set; }
24 | public string RegionDescription { get; set; }
25 |
26 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
27 | public virtual ICollection Territories { get; set; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Diagrams/LinqTypesDiagram.cd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/source/03-Queryable/06A-DbQuery.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var context = new NorthwindEntities();
14 |
15 | // DbSet and DbQuery implement IQueryable
16 | // DbQuery represents a non-generic LINQ to Entities query against a DbContext. (EF 6.x)
17 | // EF Core 2.1, useful to represent non-updateable database Views
18 | // EF Core 3, removed from EF
19 |
20 | // EF 6
21 |
22 | context.Regions.Dump();
23 | var q1 = from r in context.Regions
24 | where r.RegionID == 2
25 | select r;
26 | q1.Dump ();
--------------------------------------------------------------------------------
/source/05-Query Examples/06A-Group.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | c54576d1-888b-4050-976b-0c662e22b616
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 |
14 |
15 | var q1 = from p in Products
16 | select new {p.ProductName, p.UnitPrice};
17 | q1.Dump();
18 |
19 | var q2 = from p in Products
20 | group p by p.ProductName.Substring(0,1) into g
21 | select g;
22 | q2.Dump();
23 |
24 | var q3 = from p in Products
25 | select new {p.ProductName, p.UnitPrice} into pGroup
26 | group pGroup by pGroup.ProductName.Substring(0, 1) into g
27 | select g;
28 | q3.Dump();
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Shipper.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Shipper
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Shipper()
19 | {
20 | this.Orders = new HashSet();
21 | }
22 |
23 | public int ShipperID { get; set; }
24 | public string CompanyName { get; set; }
25 | public string Phone { get; set; }
26 |
27 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
28 | public virtual ICollection Orders { get; set; }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/source/05-Query Examples/01B-Use projection to get less data.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var context = new NorthwindEntities();
14 | // use where to filter the number of rows returned
15 | // use projection (via select) to filter the number of columns returned
16 |
17 | // Extension method syntax
18 | var q1 = Customers.Where(c => c.City.StartsWith("S"));
19 |
20 | q1.Dump();
21 |
22 | var q2 = Customers.Where(c => c.City.StartsWith("S")).Select (c=>new { c.CompanyName, c.Address, c.City});
23 |
24 | q2.Dump();
--------------------------------------------------------------------------------
/source/03-Queryable/05A-DbSet Add.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var context = new NorthwindEntities();
14 |
15 | // DbSet instance is a in memory collection
16 | // filled from the database
17 |
18 | // changes to items in the DbSet are not commited to DB, unless .SaveChanges is called.
19 |
20 | var nwRegion = new Region { RegionID = 44, RegionDescription = "NorthWest" };
21 |
22 | context.Regions.Dump("Before Add");
23 | context.Regions.Add(nwRegion);
24 | //context.SaveChanges();
25 | context.Regions.Dump("After Add");
--------------------------------------------------------------------------------
/source/03-Queryable/04-DbSet.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | c54576d1-888b-4050-976b-0c662e22b616
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var context = new NorthwindEntities();
14 |
15 | // DbSet and DbQuery implement IQueryable
16 | // DbSet represents the EF model for a database table
17 |
18 | // Regions table in EF ORM is mapped to the DbContext.Regions property
19 | // public virtual DbSet Regions { get; set; }
20 | // a row in the Regions table is mapped to the Region class
21 |
22 | context.Regions.Dump();
23 | var regionRow = context.Regions.First();
24 | regionRow.Dump();
25 |
26 |
--------------------------------------------------------------------------------
/source/03-Queryable/05B-DbSet Remove.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var context = new NorthwindEntities();
14 |
15 | // DbSet instance is a in memory collection
16 | // filled from the database
17 |
18 | // changes to items in the DbSet are not commited to DB, unless .SaveChanges is called.
19 |
20 | var nwRegion = context.Regions.Where(r => r.RegionID==44 ).Single();
21 | context.Regions.Dump("Before Remove");
22 | context.Regions.Remove(nwRegion);
23 |
24 | //context.SaveChanges();
25 | context.Regions.Dump("After Remove");
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Category.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Category
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Category()
19 | {
20 | this.Products = new HashSet();
21 | }
22 |
23 | public int CategoryID { get; set; }
24 | public string CategoryName { get; set; }
25 | public string Description { get; set; }
26 | public byte[] Picture { get; set; }
27 |
28 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
29 | public virtual ICollection Products { get; set; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/source/05-Query Examples/03-Where and Find.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // Use Find to get an entity with the specified key value
14 | // This is faster if item is cached in the context (DbContext in this example).
15 |
16 | // Microsoft Docs: Find is different from using a query:
17 | // A round-trip to the database happens if the entity
18 | // with the given key is not found in the context.
19 |
20 |
21 | Products.Where(p => p.ProductID == 4).Single().Dump();
22 | Products.Where(p => p.ProductID == 4).Single().Dump();
23 | //Products.Find(4).Dump();
24 | //Products.Find(4).Dump();
--------------------------------------------------------------------------------
/source/04-Basic Syntax/04D-Query Expression.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // instead of pipelining, add clauses to query expression
14 | var manyClauses = from p in Products
15 | orderby p.UnitPrice
16 | where p.UnitsInStock == 0
17 | select p.ProductName;
18 |
19 |
20 |
21 | manyClauses.Dump();
22 |
23 | // some operators, like Count, cannot be used in the query expression!
24 | // call them on the query variable
25 |
26 | manyClauses.Count().Dump("Call Count method");
27 |
28 | // Learn more about LINQ
29 | // https://www.linkedin.com/learning/topics/linq
--------------------------------------------------------------------------------
/source/05-Query Examples/01A-Use projection to get less data.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // Where clause filters the number of rows returned
14 | // Select clause (aka projection) filters the number of columns returned
15 |
16 | Customers.Count().Dump("# rows in Customers");
17 | var q1 = from c in Customers
18 | where c.City.StartsWith ("S")
19 | select c;
20 |
21 | // check the generated SQL, this gets all columns
22 | q1.Dump ();
23 |
24 | var q2 = from c in Customers
25 | where c.City.StartsWith ("S")
26 | select new {c.CompanyName, c.Address, c.City};
27 | q2.Dump();
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Territory.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Territory
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Territory()
19 | {
20 | this.Employees = new HashSet();
21 | }
22 |
23 | public string TerritoryID { get; set; }
24 | public string TerritoryDescription { get; set; }
25 | public int RegionID { get; set; }
26 |
27 | public virtual Region Region { get; set; }
28 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
29 | public virtual ICollection Employees { get; set; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/source/05-Query Examples/08-DateRange.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // get orders in date range
14 |
15 | TimeSpan thirtyDays = TimeSpan.FromDays(30);
16 |
17 | // get an order
18 | var q1 = from o in Orders
19 | where o.OrderID == 10250
20 | select new {o.OrderID, o.OrderDate, o.ShipName};
21 |
22 | q1.Take(1).Dump();
23 |
24 | var originalDate = q1.First().OrderDate;
25 | var futureDate = originalDate + thirtyDays;
26 | var q2= from o in Orders
27 | where o.OrderDate > originalDate & o.OrderDate < futureDate
28 | select new {o.OrderID, o.OrderDate, o.ShipName};
29 |
30 | q2.Dump();
--------------------------------------------------------------------------------
/source/05-Query Examples/02-Use Take, Skip to page data.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // use Take/Skip to get less rows without a where clause
14 | // Take: Returns contiguous elements from the start of a sequence.
15 | // Skip: Bypasses elements in a sequence and then returns the remaining elements.
16 | var q1 = from p in Products
17 | orderby p.ProductID
18 | select new {p.ProductID, p.ProductName, p.UnitPrice};
19 |
20 | var count = q1.Count();
21 |
22 | count.Dump("Products count");
23 |
24 | var pageSize = 5;
25 | q1.Take(pageSize).Dump("First page");
26 | q1.Skip(pageSize).Take (pageSize).Dump("Next page");
--------------------------------------------------------------------------------
/source/03-Queryable/02-DbContext.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 |
14 | // DbContext represents a session with a database
15 | // it is responsible for opening and closing the database connection
16 |
17 | // it manages change tracking, so that it know what SQL to generate
18 | // for updates, deletes and inserts.
19 |
20 | // it supports caching, so that subsequent request for same data hits the cache.
21 |
22 | // it uses transactions when SaveChanges is called.
23 |
24 | var context = new NorthwindEntities();
25 |
26 | var type = context.GetType();
27 | type.FullName.Dump("Context Type");
28 | type.BaseType.FullName.Dump("Base Type");
--------------------------------------------------------------------------------
/source/04-Basic Syntax/04B-Query Expression.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | // Add more clauses
14 |
15 |
16 | var allProducts = from p in Products
17 | select p;
18 | var filteredProducts = from p in Products
19 | where p.UnitsInStock ==0
20 | select p;
21 |
22 | var orderedProducts = from p in Products
23 | orderby p.UnitPrice
24 | select p;
25 |
26 | // instead of pipelining, add clauses to query expression
27 |
28 | allProducts.Dump();
29 | filteredProducts.Dump();
30 | orderedProducts.Dump();
31 |
32 |
33 |
34 | // Learn more about LINQ
35 | // https://www.linkedin.com/learning/topics/linq
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Contact.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Contact
16 | {
17 | public int ContactID { get; set; }
18 | public string ContactType { get; set; }
19 | public string CompanyName { get; set; }
20 | public string ContactName { get; set; }
21 | public string ContactTitle { get; set; }
22 | public string Address { get; set; }
23 | public string City { get; set; }
24 | public string Region { get; set; }
25 | public string PostalCode { get; set; }
26 | public string Country { get; set; }
27 | public string Phone { get; set; }
28 | public string Extension { get; set; }
29 | public string Fax { get; set; }
30 | public string HomePage { get; set; }
31 | public string PhotoPath { get; set; }
32 | public byte[] Photo { get; set; }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/source/OtherExamples/02-SQL.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | 54bf9502-9daf-4093-88e8-7177c129999f
4 | 2
5 | System.Data.SqlServerCe.4.0
6 | <ApplicationData>\LINQPad\DemoDB.sdf
7 | true
8 | true
9 |
10 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\DB\System.Data.SqlServerCe.dll
11 | System.Data.SqlClient
12 | System.Data.SqlServerCe
13 | System.Numerics
14 |
15 |
16 | void Main()
17 | {
18 | // Represents the main entry point for the LINQ to SQL framework.
19 | string cnString = @"data source='C:\Users\WR\AppData\Roaming\LINQPad\DemoDB.sdf'";
20 |
21 | using (var conn = new System.Data.SqlServerCe.SqlCeConnection(cnString))
22 | {
23 | conn.Open();
24 |
25 | var context = GetDataContext(conn);
26 |
27 | context.
28 | conn.Close();
29 |
30 | }
31 |
32 |
33 | }
34 |
35 | // Define other methods and classes here
36 | public DataContext GetDataContext (SqlCeConnection conn)
37 | {
38 | var myContext = new DataContext(conn,);
39 | var product = context.Products.Where(p => p.Id == productId).SingleOrDefault();
40 | return null;
41 | }
--------------------------------------------------------------------------------
/source/OtherExamples/05-Dataset.linq:
--------------------------------------------------------------------------------
1 |
2 | <ProgramFilesX86>\Microsoft Visual Studio\Shared\Packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll
3 | System.Data.SqlClient
4 | System.Data.SqlServerCe
5 | System.Numerics
6 |
7 |
8 | // LINQPad provides an easy way to get data context for a database
9 | // this example bypasses the LINQPad system and uses basic ADO.NET
10 | // Note: since this is .NET core
11 | // add System.Data.Common and System.Data.SqlClient nuget packages.
12 | void Main()
13 | {
14 |
15 | string cnString = @"data source='C:\Users\WR\AppData\Roaming\LINQPad\DemoDB.sdf'";
16 |
17 |
18 | using (var conn = new System.Data.SqlServerCe.SqlCeConnection(cnString))
19 | {
20 | conn.Open();
21 |
22 | var ds = GetDataSet (conn);
23 |
24 | ds.Dump();
25 | conn.Close();
26 |
27 | }
28 |
29 | }
30 |
31 |
32 | public DataSet GetDataSet(SqlCeConnection conn)
33 | {
34 | var dataSet = new DataSet("NorthwindDemo");
35 | var shippersAdapter= new SqlCeDataAdapter("Select * From Shippers", conn);
36 | shippersAdapter.Fill(dataSet, "Shippers");
37 | var productsAdapter = new SqlCeDataAdapter("Select [Product Name],[Unit Price], [Units In Stock]From Products ", conn);
38 | productsAdapter.Fill(dataSet, "Products");
39 |
40 |
41 | return dataSet;
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/source/03-Queryable/07B-Interfaces.linq:
--------------------------------------------------------------------------------
1 |
2 |
3 | aef7d1f3-9ecd-4b72-8ac7-667df71c9301
4 | true
5 | EntityFrameworkDbContext
6 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe
7 | ConsoleForEF.NorthwindEntities
8 | C:\Users\WR\Source\Repos\linq-databases-2858036\source\Assets\ExeEF\ConsoleForEF.exe.config
9 |
10 | C:\Users\WR\Source\Repos\linq-2833070\source\VisualStudio\CourseLib\bin\Debug\netstandard2.0\CourseLib.dll
11 |
12 |
13 | var numbers = new List { 3, 5, 7, 9, 11 };
14 | var q1 = from n in numbers
15 | where n < 20
16 | select n;
17 |
18 | q1.Dump("Linq to Objects query");
19 | // The where clause uses the Enumerable.Where
20 | // Implmented via an anonymous method
21 | q1.ToString().Dump("Using the Enumerable Where");
22 |
23 | // LINQ to EF queries types with IQueryable
24 | // LINQ to EF creates an expression tree
25 | // Uses the Queryable.Where
26 |
27 | var q2 = from p in Products
28 | where p.UnitPrice > 100
29 | select new { p.ProductName, p.UnitPrice };
30 |
31 | q2.Dump("Linq to EF, query");
32 | q2.GetType().GetInterfaces().Dump("DbQuery interfaces");
33 |
34 | q2.ToString().Dump("Using the Where");
35 | q2.Expression.Dump();
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("ConsoleForEF")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ConsoleForEF")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("576e8704-2ffb-4211-9ae9-2ce09902ed87")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Customer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Customer
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Customer()
19 | {
20 | this.Orders = new HashSet();
21 | }
22 |
23 | public string CustomerID { get; set; }
24 | public string CompanyName { get; set; }
25 | public string ContactName { get; set; }
26 | public string ContactTitle { get; set; }
27 | public string Address { get; set; }
28 | public string City { get; set; }
29 | public string Region { get; set; }
30 | public string PostalCode { get; set; }
31 | public string Country { get; set; }
32 | public string Phone { get; set; }
33 | public string Fax { get; set; }
34 |
35 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
36 | public virtual ICollection Orders { get; set; }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Supplier.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Supplier
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Supplier()
19 | {
20 | this.Products = new HashSet();
21 | }
22 |
23 | public int SupplierID { get; set; }
24 | public string CompanyName { get; set; }
25 | public string ContactName { get; set; }
26 | public string ContactTitle { get; set; }
27 | public string Address { get; set; }
28 | public string City { get; set; }
29 | public string Region { get; set; }
30 | public string PostalCode { get; set; }
31 | public string Country { get; set; }
32 | public string Phone { get; set; }
33 | public string Fax { get; set; }
34 | public string HomePage { get; set; }
35 |
36 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
37 | public virtual ICollection Products { get; set; }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/NorthwindModel.Context.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Data.Entity;
14 | using System.Data.Entity.Infrastructure;
15 |
16 | public partial class NorthwindEntities : DbContext
17 | {
18 | public NorthwindEntities()
19 | : base("name=NorthwindEntities")
20 | {
21 | }
22 |
23 | protected override void OnModelCreating(DbModelBuilder modelBuilder)
24 | {
25 | throw new UnintentionalCodeFirstException();
26 | }
27 |
28 | public virtual DbSet Categories { get; set; }
29 | public virtual DbSet Contacts { get; set; }
30 | public virtual DbSet Customers { get; set; }
31 | public virtual DbSet Employees { get; set; }
32 | public virtual DbSet Order_Details { get; set; }
33 | public virtual DbSet Orders { get; set; }
34 | public virtual DbSet Products { get; set; }
35 | public virtual DbSet Regions { get; set; }
36 | public virtual DbSet Shippers { get; set; }
37 | public virtual DbSet Suppliers { get; set; }
38 | public virtual DbSet Territories { get; set; }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Product.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Product
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Product()
19 | {
20 | this.Order_Details = new HashSet();
21 | }
22 |
23 | public int ProductID { get; set; }
24 | public string ProductName { get; set; }
25 | public Nullable SupplierID { get; set; }
26 | public Nullable CategoryID { get; set; }
27 | public string QuantityPerUnit { get; set; }
28 | public Nullable UnitPrice { get; set; }
29 | public Nullable UnitsInStock { get; set; }
30 | public Nullable UnitsOnOrder { get; set; }
31 | public Nullable ReorderLevel { get; set; }
32 | public bool Discontinued { get; set; }
33 |
34 | public virtual Category Category { get; set; }
35 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
36 | public virtual ICollection Order_Details { get; set; }
37 | public virtual Supplier Supplier { get; set; }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/source/Assets/ExeEF/ConsoleForEF.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # .NET Essentials: LINQ for Databases
2 | This is the repository for the LinkedIn Learning course .NET Essentials: LINQ for Databases. The full course is available from [LinkedIn Learning][lil-course-url].
3 |
4 | ![.NET Essentials: LINQ for Databases][lil-thumbnail-url]
5 | The first explanation you typically hear about Microsoft LINQ is that it provides an in-language query tool to manipulate the contents of arrays and lists. Explore LINQ further and you’ll find it works with other popular data sources like databases and XML files. That makes it a universal query tool that simplifies working with any data source. In this course, part of a three-course series, LinkedIn Learning staff author Walt Ritscher uses LINQPad, a lightweight, powerful code editor, to illustrate useful topics like queryable types, basic query syntax, finding data by date range, and how to use LINQ queries to reduce database network traffic. After completing this course, you’ll have a solid foundation on using LINQ to query database and Entity Framework data.
6 |
7 | ## Instructions
8 | This repository has one MAIN branch for the course.
9 |
10 | ## Installing
11 | 1. To use these exercise files, you must have the following installed:
12 | - [Visual Studio](https://visualstudio.microsoft.com/)
13 | - [LINQPad](https://www.linqpad.net/)
14 | 2. Clone this repository into your local machine using the Visual Studio, or OS command line tool (Powershell, Windows Terminal) or MAC equivalent .
15 | 3. See the intro chapter for information about this course Git branches.
16 |
17 | ### Instructor
18 |
19 | **Walt Ritscher **
20 |
21 | _Walt Ritscher is a programmer, UI designer, and staff author at LinkedIn Learning._
22 |
23 | Check out some of my other courses on [LinkedIn Learning](https://www.linkedin.com/learning/instructors/walt-ritscher?u=104).
24 |
25 | [lil-course-url]: https://www.linkedin.com/learning/dot-net-essentials-linq-for-databases
26 | [lil-thumbnail-url]: https://cdn.lynda.com/course/2858036/2858036-1610558892801-16x9.jpg
27 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Order.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Order
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Order()
19 | {
20 | this.Order_Details = new HashSet();
21 | }
22 |
23 | public int OrderID { get; set; }
24 | public string CustomerID { get; set; }
25 | public Nullable EmployeeID { get; set; }
26 | public Nullable OrderDate { get; set; }
27 | public Nullable RequiredDate { get; set; }
28 | public Nullable ShippedDate { get; set; }
29 | public Nullable ShipVia { get; set; }
30 | public Nullable Freight { get; set; }
31 | public string ShipName { get; set; }
32 | public string ShipAddress { get; set; }
33 | public string ShipCity { get; set; }
34 | public string ShipRegion { get; set; }
35 | public string ShipPostalCode { get; set; }
36 | public string ShipCountry { get; set; }
37 |
38 | public virtual Customer Customer { get; set; }
39 | public virtual Employee Employee { get; set; }
40 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
41 | public virtual ICollection Order_Details { get; set; }
42 | public virtual Shipper Shipper { get; set; }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/Employee.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace ConsoleForEF
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Employee
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Employee()
19 | {
20 | this.Employees1 = new HashSet();
21 | this.Orders = new HashSet();
22 | this.Territories = new HashSet();
23 | }
24 |
25 | public int EmployeeID { get; set; }
26 | public string LastName { get; set; }
27 | public string FirstName { get; set; }
28 | public string Title { get; set; }
29 | public string TitleOfCourtesy { get; set; }
30 | public Nullable BirthDate { get; set; }
31 | public Nullable HireDate { get; set; }
32 | public string Address { get; set; }
33 | public string City { get; set; }
34 | public string Region { get; set; }
35 | public string PostalCode { get; set; }
36 | public string Country { get; set; }
37 | public string HomePhone { get; set; }
38 | public string Extension { get; set; }
39 | public byte[] Photo { get; set; }
40 | public string Notes { get; set; }
41 | public Nullable ReportsTo { get; set; }
42 | public string PhotoPath { get; set; }
43 |
44 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
45 | public virtual ICollection Employees1 { get; set; }
46 | public virtual Employee Employee1 { get; set; }
47 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
48 | public virtual ICollection Orders { get; set; }
49 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
50 | public virtual ICollection Territories { get; set; }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/NorthwindModel.edmx.diagram:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | LinkedIn Learning Exercise Files License Agreement
2 | ==================================================
3 |
4 | This License Agreement (the "Agreement") is a binding legal agreement
5 | between you (as an individual or entity, as applicable) and LinkedIn
6 | Corporation (“LinkedIn”). By downloading or using the LinkedIn Learning
7 | exercise files in this repository (“Licensed Materials”), you agree to
8 | be bound by the terms of this Agreement. If you do not agree to these
9 | terms, do not download or use the Licensed Materials.
10 |
11 | 1. License.
12 | - a. Subject to the terms of this Agreement, LinkedIn hereby grants LinkedIn
13 | members during their LinkedIn Learning subscription a non-exclusive,
14 | non-transferable copyright license, for internal use only, to 1) make a
15 | reasonable number of copies of the Licensed Materials, and 2) make
16 | derivative works of the Licensed Materials for the sole purpose of
17 | practicing skills taught in LinkedIn Learning courses.
18 | - b. Distribution. Unless otherwise noted in the Licensed Materials, subject
19 | to the terms of this Agreement, LinkedIn hereby grants LinkedIn members
20 | with a LinkedIn Learning subscription a non-exclusive, non-transferable
21 | copyright license to distribute the Licensed Materials, except the
22 | Licensed Materials may not be included in any product or service (or
23 | otherwise used) to instruct or educate others.
24 |
25 | 2. Restrictions and Intellectual Property.
26 | - a. You may not to use, modify, copy, make derivative works of, publish,
27 | distribute, rent, lease, sell, sublicense, assign or otherwise transfer the
28 | Licensed Materials, except as expressly set forth above in Section 1.
29 | - b. Linkedin (and its licensors) retains its intellectual property rights
30 | in the Licensed Materials. Except as expressly set forth in Section 1,
31 | LinkedIn grants no licenses.
32 | - c. You indemnify LinkedIn and its licensors and affiliates for i) any
33 | alleged infringement or misappropriation of any intellectual property rights
34 | of any third party based on modifications you make to the Licensed Materials,
35 | ii) any claims arising from your use or distribution of all or part of the
36 | Licensed Materials and iii) a breach of this Agreement. You will defend, hold
37 | harmless, and indemnify LinkedIn and its affiliates (and our and their
38 | respective employees, shareholders, and directors) from any claim or action
39 | brought by a third party, including all damages, liabilities, costs and
40 | expenses, including reasonable attorneys’ fees, to the extent resulting from,
41 | alleged to have resulted from, or in connection with: (a) your breach of your
42 | obligations herein; or (b) your use or distribution of any Licensed Materials.
43 |
44 | 3. Open source. This code may include open source software, which may be
45 | subject to other license terms as provided in the files.
46 |
47 | 4. Warranty Disclaimer. LINKEDIN PROVIDES THE LICENSED MATERIALS ON AN “AS IS”
48 | AND “AS AVAILABLE” BASIS. LINKEDIN MAKES NO REPRESENTATION OR WARRANTY,
49 | WHETHER EXPRESS OR IMPLIED, ABOUT THE LICENSED MATERIALS, INCLUDING ANY
50 | REPRESENTATION THAT THE LICENSED MATERIALS WILL BE FREE OF ERRORS, BUGS OR
51 | INTERRUPTIONS, OR THAT THE LICENSED MATERIALS ARE ACCURATE, COMPLETE OR
52 | OTHERWISE VALID. TO THE FULLEST EXTENT PERMITTED BY LAW, LINKEDIN AND ITS
53 | AFFILIATES DISCLAIM ANY IMPLIED OR STATUTORY WARRANTY OR CONDITION, INCLUDING
54 | ANY IMPLIED WARRANTY OR CONDITION OF MERCHANTABILITY OR FITNESS FOR A
55 | PARTICULAR PURPOSE, AVAILABILITY, SECURITY, TITLE AND/OR NON-INFRINGEMENT.
56 | YOUR USE OF THE LICENSED MATERIALS IS AT YOUR OWN DISCRETION AND RISK, AND
57 | YOU WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGE THAT RESULTS FROM USE OF THE
58 | LICENSED MATERIALS TO YOUR COMPUTER SYSTEM OR LOSS OF DATA. NO ADVICE OR
59 | INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM US OR THROUGH OR
60 | FROM THE LICENSED MATERIALS WILL CREATE ANY WARRANTY OR CONDITION NOT
61 | EXPRESSLY STATED IN THESE TERMS.
62 |
63 | 5. Limitation of Liability. LINKEDIN SHALL NOT BE LIABLE FOR ANY INDIRECT,
64 | INCIDENTAL, SPECIAL, PUNITIVE, CONSEQUENTIAL OR EXEMPLARY DAMAGES, INCLUDING
65 | BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER
66 | INTANGIBLE LOSSES . IN NO EVENT WILL LINKEDIN'S AGGREGATE LIABILITY TO YOU
67 | EXCEED $100. THIS LIMITATION OF LIABILITY SHALL:
68 | - i. APPLY REGARDLESS OF WHETHER (A) YOU BASE YOUR CLAIM ON CONTRACT, TORT,
69 | STATUTE, OR ANY OTHER LEGAL THEORY, (B) WE KNEW OR SHOULD HAVE KNOWN ABOUT
70 | THE POSSIBILITY OF SUCH DAMAGES, OR (C) THE LIMITED REMEDIES PROVIDED IN THIS
71 | SECTION FAIL OF THEIR ESSENTIAL PURPOSE; AND
72 | - ii. NOT APPLY TO ANY DAMAGE THAT LINKEDIN MAY CAUSE YOU INTENTIONALLY OR
73 | KNOWINGLY IN VIOLATION OF THESE TERMS OR APPLICABLE LAW, OR AS OTHERWISE
74 | MANDATED BY APPLICABLE LAW THAT CANNOT BE DISCLAIMED IN THESE TERMS.
75 |
76 | 6. Termination. This Agreement automatically terminates upon your breach of
77 | this Agreement or termination of your LinkedIn Learning subscription. On
78 | termination, all licenses granted under this Agreement will terminate
79 | immediately and you will delete the Licensed Materials. Sections 2-7 of this
80 | Agreement survive any termination of this Agreement. LinkedIn may discontinue
81 | the availability of some or all of the Licensed Materials at any time for any
82 | reason.
83 |
84 | 7. Miscellaneous. This Agreement will be governed by and construed in
85 | accordance with the laws of the State of California without regard to conflict
86 | of laws principles. The exclusive forum for any disputes arising out of or
87 | relating to this Agreement shall be an appropriate federal or state court
88 | sitting in the County of Santa Clara, State of California. If LinkedIn does
89 | not act to enforce a breach of this Agreement, that does not mean that
90 | LinkedIn has waived its right to enforce this Agreement. The Agreement does
91 | not create a partnership, agency relationship, or joint venture between the
92 | parties. Neither party has the power or authority to bind the other or to
93 | create any obligation or responsibility on behalf of the other. You may not,
94 | without LinkedIn’s prior written consent, assign or delegate any rights or
95 | obligations under these terms, including in connection with a change of
96 | control. Any purported assignment and delegation shall be ineffective. The
97 | Agreement shall bind and inure to the benefit of the parties, their respective
98 | successors and permitted assigns. If any provision of the Agreement is
99 | unenforceable, that provision will be modified to render it enforceable to the
100 | extent possible to give effect to the parties’ intentions and the remaining
101 | provisions will not be affected. This Agreement is the only agreement between
102 | you and LinkedIn regarding the Licensed Materials, and supersedes all prior
103 | agreements relating to the Licensed Materials.
104 |
105 | Last Updated: March 2019
106 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 | artifacts/
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_h.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *_wpftmp.csproj
83 | *.log
84 | *.vspscc
85 | *.vssscc
86 | .builds
87 | *.pidb
88 | *.svclog
89 | *.scc
90 |
91 | # Chutzpah Test files
92 | _Chutzpah*
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opendb
99 | *.opensdf
100 | *.sdf
101 | *.cachefile
102 | *.VC.db
103 | *.VC.VC.opendb
104 |
105 | # Visual Studio profiler
106 | *.psess
107 | *.vsp
108 | *.vspx
109 | *.sap
110 |
111 | # Visual Studio Trace Files
112 | *.e2e
113 |
114 | # TFS 2012 Local Workspace
115 | $tf/
116 |
117 | # Guidance Automation Toolkit
118 | *.gpState
119 |
120 | # ReSharper is a .NET coding add-in
121 | _ReSharper*/
122 | *.[Rr]e[Ss]harper
123 | *.DotSettings.user
124 |
125 | # JustCode is a .NET coding add-in
126 | .JustCode
127 |
128 | # TeamCity is a build add-in
129 | _TeamCity*
130 |
131 | # DotCover is a Code Coverage Tool
132 | *.dotCover
133 |
134 | # AxoCover is a Code Coverage Tool
135 | .axoCover/*
136 | !.axoCover/settings.json
137 |
138 | # Visual Studio code coverage results
139 | *.coverage
140 | *.coveragexml
141 |
142 | # NCrunch
143 | _NCrunch_*
144 | .*crunch*.local.xml
145 | nCrunchTemp_*
146 |
147 | # MightyMoose
148 | *.mm.*
149 | AutoTest.Net/
150 |
151 | # Web workbench (sass)
152 | .sass-cache/
153 |
154 | # Installshield output folder
155 | [Ee]xpress/
156 |
157 | # DocProject is a documentation generator add-in
158 | DocProject/buildhelp/
159 | DocProject/Help/*.HxT
160 | DocProject/Help/*.HxC
161 | DocProject/Help/*.hhc
162 | DocProject/Help/*.hhk
163 | DocProject/Help/*.hhp
164 | DocProject/Help/Html2
165 | DocProject/Help/html
166 |
167 | # Click-Once directory
168 | publish/
169 |
170 | # Publish Web Output
171 | *.[Pp]ublish.xml
172 | *.azurePubxml
173 | # Note: Comment the next line if you want to checkin your web deploy settings,
174 | # but database connection strings (with potential passwords) will be unencrypted
175 | *.pubxml
176 | *.publishproj
177 |
178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
179 | # checkin your Azure Web App publish settings, but sensitive information contained
180 | # in these scripts will be unencrypted
181 | PublishScripts/
182 |
183 | # NuGet Packages
184 | *.nupkg
185 | # The packages folder can be ignored because of Package Restore
186 | **/[Pp]ackages/*
187 | # except build/, which is used as an MSBuild target.
188 | !**/[Pp]ackages/build/
189 | # Uncomment if necessary however generally it will be regenerated when needed
190 | #!**/[Pp]ackages/repositories.config
191 | # NuGet v3's project.json files produces more ignorable files
192 | *.nuget.props
193 | *.nuget.targets
194 |
195 | # Microsoft Azure Build Output
196 | csx/
197 | *.build.csdef
198 |
199 | # Microsoft Azure Emulator
200 | ecf/
201 | rcf/
202 |
203 | # Windows Store app package directories and files
204 | AppPackages/
205 | BundleArtifacts/
206 | Package.StoreAssociation.xml
207 | _pkginfo.txt
208 | *.appx
209 |
210 | # Visual Studio cache files
211 | # files ending in .cache can be ignored
212 | *.[Cc]ache
213 | # but keep track of directories ending in .cache
214 | !?*.[Cc]ache/
215 |
216 | # Others
217 | ClientBin/
218 | ~$*
219 | *~
220 | *.dbmdl
221 | *.dbproj.schemaview
222 | *.jfm
223 | *.pfx
224 | *.publishsettings
225 | orleans.codegen.cs
226 |
227 | # Including strong name files can present a security risk
228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
229 | #*.snk
230 |
231 | # Since there are multiple workflows, uncomment next line to ignore bower_components
232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
233 | #bower_components/
234 |
235 | # RIA/Silverlight projects
236 | Generated_Code/
237 |
238 | # Backup & report files from converting an old project file
239 | # to a newer Visual Studio version. Backup files are not needed,
240 | # because we have git ;-)
241 | _UpgradeReport_Files/
242 | Backup*/
243 | UpgradeLog*.XML
244 | UpgradeLog*.htm
245 | ServiceFabricBackup/
246 | *.rptproj.bak
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 | *.ndf
252 |
253 | # Business Intelligence projects
254 | *.rdl.data
255 | *.bim.layout
256 | *.bim_*.settings
257 | *.rptproj.rsuser
258 | *- Backup*.rdl
259 |
260 | # Microsoft Fakes
261 | FakesAssemblies/
262 |
263 | # GhostDoc plugin setting file
264 | *.GhostDoc.xml
265 |
266 | # Node.js Tools for Visual Studio
267 | .ntvs_analysis.dat
268 | node_modules/
269 |
270 | # Visual Studio 6 build log
271 | *.plg
272 |
273 | # Visual Studio 6 workspace options file
274 | *.opt
275 |
276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
277 | *.vbw
278 |
279 | # Visual Studio LightSwitch build output
280 | **/*.HTMLClient/GeneratedArtifacts
281 | **/*.DesktopClient/GeneratedArtifacts
282 | **/*.DesktopClient/ModelManifest.xml
283 | **/*.Server/GeneratedArtifacts
284 | **/*.Server/ModelManifest.xml
285 | _Pvt_Extensions
286 |
287 | # Paket dependency manager
288 | .paket/paket.exe
289 | paket-files/
290 |
291 | # FAKE - F# Make
292 | .fake/
293 |
294 | # JetBrains Rider
295 | .idea/
296 | *.sln.iml
297 |
298 | # CodeRush personal settings
299 | .cr/personal
300 |
301 | # Python Tools for Visual Studio (PTVS)
302 | __pycache__/
303 | *.pyc
304 |
305 | # Cake - Uncomment if you are using it
306 | # tools/**
307 | # !tools/packages.config
308 |
309 | # Tabs Studio
310 | *.tss
311 |
312 | # Telerik's JustMock configuration file
313 | *.jmconfig
314 |
315 | # BizTalk build output
316 | *.btp.cs
317 | *.btm.cs
318 | *.odx.cs
319 | *.xsd.cs
320 |
321 | # OpenCover UI analysis results
322 | OpenCover/
323 |
324 | # Azure Stream Analytics local run output
325 | ASALocalRun/
326 |
327 | # MSBuild Binary and Structured Log
328 | *.binlog
329 |
330 | # NVidia Nsight GPU debugger configuration file
331 | *.nvuser
332 |
333 | # MFractors (Xamarin productivity tool) working folder
334 | .mfractor/
335 |
336 | # Local History for Visual Studio
337 | .localhistory/
338 |
339 | # BeatPulse healthcheck temp database
340 | healthchecksdb
341 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/ToursModel.edmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/ConsoleForEF.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {576E8704-2FFB-4211-9AE9-2CE09902ED87}
8 | Exe
9 | ConsoleForEF
10 | ConsoleForEF
11 | v4.7
12 | 512
13 | true
14 | true
15 | false
16 | publish\
17 | true
18 | Disk
19 | false
20 | Foreground
21 | 7
22 | Days
23 | false
24 | false
25 | true
26 | 0
27 | 1.0.0.%2a
28 | false
29 | true
30 |
31 |
32 | AnyCPU
33 | true
34 | full
35 | false
36 | bin\Debug\
37 | DEBUG;TRACE
38 | prompt
39 | 4
40 |
41 |
42 | AnyCPU
43 | pdbonly
44 | true
45 | bin\Release\
46 | TRACE
47 | prompt
48 | 4
49 |
50 |
51 |
52 | ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll
53 |
54 |
55 | ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | NorthwindModel.tt
72 |
73 |
74 | NorthwindModel.tt
75 |
76 |
77 | NorthwindModel.tt
78 |
79 |
80 | NorthwindModel.tt
81 |
82 |
83 | True
84 | True
85 | NorthwindModel.Context.tt
86 |
87 |
88 | True
89 | True
90 | NorthwindModel.tt
91 |
92 |
93 | True
94 | True
95 | NorthwindModel.edmx
96 |
97 |
98 | NorthwindModel.tt
99 |
100 |
101 | NorthwindModel.tt
102 |
103 |
104 | NorthwindModel.tt
105 |
106 |
107 |
108 |
109 | NorthwindModel.tt
110 |
111 |
112 | NorthwindModel.tt
113 |
114 |
115 | NorthwindModel.tt
116 |
117 |
118 | NorthwindModel.tt
119 |
120 |
121 | ToursModel.tt
122 |
123 |
124 | ToursModel.tt
125 |
126 |
127 | True
128 | True
129 | ToursModel.Context.tt
130 |
131 |
132 | True
133 | True
134 | ToursModel.tt
135 |
136 |
137 | True
138 | True
139 | ToursModel.edmx
140 |
141 |
142 | ToursModel.tt
143 |
144 |
145 |
146 |
147 |
148 | EntityModelCodeGenerator
149 | ToursModel.Designer.cs
150 |
151 |
152 |
153 |
154 | EntityModelCodeGenerator
155 | NorthwindModel.Designer.cs
156 |
157 |
158 | NorthwindModel.edmx
159 |
160 |
161 |
162 | ToursModel.edmx
163 |
164 |
165 |
166 |
167 | TextTemplatingFileGenerator
168 | NorthwindModel.edmx
169 | NorthwindModel.Context.cs
170 |
171 |
172 | TextTemplatingFileGenerator
173 | NorthwindModel.edmx
174 | NorthwindModel.cs
175 |
176 |
177 | Always
178 |
179 |
180 | Always
181 | NorthwindV13.MDF
182 |
183 |
184 | Always
185 |
186 |
187 | TextTemplatingFileGenerator
188 | ToursModel.Context.cs
189 | ToursModel.edmx
190 |
191 |
192 | TextTemplatingFileGenerator
193 | ToursModel.edmx
194 | ToursModel.cs
195 |
196 |
197 | Always
198 | Tours.mdf
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 | False
207 | Microsoft .NET Framework 4.7 %28x86 and x64%29
208 | true
209 |
210 |
211 | False
212 | .NET Framework 3.5 SP1
213 | false
214 |
215 |
216 |
217 |
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/ToursModel.Context.tt:
--------------------------------------------------------------------------------
1 | <#@ template language="C#" debug="false" hostspecific="true"#>
2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@
3 | output extension=".cs"#><#
4 |
5 | const string inputFile = @"ToursModel.edmx";
6 | var textTransform = DynamicTextTransformation.Create(this);
7 | var code = new CodeGenerationTools(this);
8 | var ef = new MetadataTools(this);
9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10 | var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
11 | var itemCollection = loader.CreateEdmItemCollection(inputFile);
12 | var modelNamespace = loader.GetModelNamespace(inputFile);
13 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
14 |
15 | var container = itemCollection.OfType().FirstOrDefault();
16 | if (container == null)
17 | {
18 | return string.Empty;
19 | }
20 | #>
21 | //------------------------------------------------------------------------------
22 | //
23 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
24 | //
25 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
26 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
27 | //
28 | //------------------------------------------------------------------------------
29 |
30 | <#
31 |
32 | var codeNamespace = code.VsNamespaceSuggestion();
33 | if (!String.IsNullOrEmpty(codeNamespace))
34 | {
35 | #>
36 | namespace <#=code.EscapeNamespace(codeNamespace)#>
37 | {
38 | <#
39 | PushIndent(" ");
40 | }
41 |
42 | #>
43 | using System;
44 | using System.Data.Entity;
45 | using System.Data.Entity.Infrastructure;
46 | <#
47 | if (container.FunctionImports.Any())
48 | {
49 | #>
50 | using System.Data.Entity.Core.Objects;
51 | using System.Linq;
52 | <#
53 | }
54 | #>
55 |
56 | <#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
57 | {
58 | public <#=code.Escape(container)#>()
59 | : base("name=<#=container.Name#>")
60 | {
61 | <#
62 | if (!loader.IsLazyLoadingEnabled(container))
63 | {
64 | #>
65 | this.Configuration.LazyLoadingEnabled = false;
66 | <#
67 | }
68 |
69 | foreach (var entitySet in container.BaseEntitySets.OfType())
70 | {
71 | // Note: the DbSet members are defined below such that the getter and
72 | // setter always have the same accessibility as the DbSet definition
73 | if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
74 | {
75 | #>
76 | <#=codeStringGenerator.DbSetInitializer(entitySet)#>
77 | <#
78 | }
79 | }
80 | #>
81 | }
82 |
83 | protected override void OnModelCreating(DbModelBuilder modelBuilder)
84 | {
85 | throw new UnintentionalCodeFirstException();
86 | }
87 |
88 | <#
89 | foreach (var entitySet in container.BaseEntitySets.OfType())
90 | {
91 | #>
92 | <#=codeStringGenerator.DbSet(entitySet)#>
93 | <#
94 | }
95 |
96 | foreach (var edmFunction in container.FunctionImports)
97 | {
98 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
99 | }
100 | #>
101 | }
102 | <#
103 |
104 | if (!String.IsNullOrEmpty(codeNamespace))
105 | {
106 | PopIndent();
107 | #>
108 | }
109 | <#
110 | }
111 | #>
112 | <#+
113 |
114 | private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
115 | {
116 | if (typeMapper.IsComposable(edmFunction))
117 | {
118 | #>
119 |
120 | [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
121 | <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
122 | {
123 | <#+
124 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
125 | #>
126 | <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
127 | }
128 | <#+
129 | }
130 | else
131 | {
132 | #>
133 |
134 | <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
135 | {
136 | <#+
137 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
138 | #>
139 | <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
140 | }
141 | <#+
142 | if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
143 | {
144 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
145 | }
146 | }
147 | }
148 |
149 | public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
150 | {
151 | #>
152 | var <#=name#> = <#=isNotNull#> ?
153 | <#=notNullInit#> :
154 | <#=nullInit#>;
155 |
156 | <#+
157 | }
158 |
159 | public const string TemplateId = "CSharp_DbContext_Context_EF6";
160 |
161 | public class CodeStringGenerator
162 | {
163 | private readonly CodeGenerationTools _code;
164 | private readonly TypeMapper _typeMapper;
165 | private readonly MetadataTools _ef;
166 |
167 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
168 | {
169 | ArgumentNotNull(code, "code");
170 | ArgumentNotNull(typeMapper, "typeMapper");
171 | ArgumentNotNull(ef, "ef");
172 |
173 | _code = code;
174 | _typeMapper = typeMapper;
175 | _ef = ef;
176 | }
177 |
178 | public string Property(EdmProperty edmProperty)
179 | {
180 | return string.Format(
181 | CultureInfo.InvariantCulture,
182 | "{0} {1} {2} {{ {3}get; {4}set; }}",
183 | Accessibility.ForProperty(edmProperty),
184 | _typeMapper.GetTypeName(edmProperty.TypeUsage),
185 | _code.Escape(edmProperty),
186 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
187 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
188 | }
189 |
190 | public string NavigationProperty(NavigationProperty navProp)
191 | {
192 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
193 | return string.Format(
194 | CultureInfo.InvariantCulture,
195 | "{0} {1} {2} {{ {3}get; {4}set; }}",
196 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
197 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
198 | _code.Escape(navProp),
199 | _code.SpaceAfter(Accessibility.ForGetter(navProp)),
200 | _code.SpaceAfter(Accessibility.ForSetter(navProp)));
201 | }
202 |
203 | public string AccessibilityAndVirtual(string accessibility)
204 | {
205 | return accessibility + (accessibility != "private" ? " virtual" : "");
206 | }
207 |
208 | public string EntityClassOpening(EntityType entity)
209 | {
210 | return string.Format(
211 | CultureInfo.InvariantCulture,
212 | "{0} {1}partial class {2}{3}",
213 | Accessibility.ForType(entity),
214 | _code.SpaceAfter(_code.AbstractOption(entity)),
215 | _code.Escape(entity),
216 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
217 | }
218 |
219 | public string EnumOpening(SimpleType enumType)
220 | {
221 | return string.Format(
222 | CultureInfo.InvariantCulture,
223 | "{0} enum {1} : {2}",
224 | Accessibility.ForType(enumType),
225 | _code.Escape(enumType),
226 | _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
227 | }
228 |
229 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
230 | {
231 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
232 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
233 | {
234 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
235 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
236 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
237 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
238 | }
239 | }
240 |
241 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
242 | {
243 | var parameters = _typeMapper.GetParameters(edmFunction);
244 |
245 | return string.Format(
246 | CultureInfo.InvariantCulture,
247 | "{0} IQueryable<{1}> {2}({3})",
248 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
249 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
250 | _code.Escape(edmFunction),
251 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
252 | }
253 |
254 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
255 | {
256 | var parameters = _typeMapper.GetParameters(edmFunction);
257 |
258 | return string.Format(
259 | CultureInfo.InvariantCulture,
260 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
261 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
262 | edmFunction.NamespaceName,
263 | edmFunction.Name,
264 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
265 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
266 | }
267 |
268 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
269 | {
270 | var parameters = _typeMapper.GetParameters(edmFunction);
271 | var returnType = _typeMapper.GetReturnType(edmFunction);
272 |
273 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
274 | if (includeMergeOption)
275 | {
276 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
277 | }
278 |
279 | return string.Format(
280 | CultureInfo.InvariantCulture,
281 | "{0} {1} {2}({3})",
282 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
283 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
284 | _code.Escape(edmFunction),
285 | paramList);
286 | }
287 |
288 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
289 | {
290 | var parameters = _typeMapper.GetParameters(edmFunction);
291 | var returnType = _typeMapper.GetReturnType(edmFunction);
292 |
293 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
294 | if (includeMergeOption)
295 | {
296 | callParams = ", mergeOption" + callParams;
297 | }
298 |
299 | return string.Format(
300 | CultureInfo.InvariantCulture,
301 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
302 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
303 | edmFunction.Name,
304 | callParams);
305 | }
306 |
307 | public string DbSet(EntitySet entitySet)
308 | {
309 | return string.Format(
310 | CultureInfo.InvariantCulture,
311 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
312 | Accessibility.ForReadOnlyProperty(entitySet),
313 | _typeMapper.GetTypeName(entitySet.ElementType),
314 | _code.Escape(entitySet));
315 | }
316 |
317 | public string DbSetInitializer(EntitySet entitySet)
318 | {
319 | return string.Format(
320 | CultureInfo.InvariantCulture,
321 | "{0} = Set<{1}>();",
322 | _code.Escape(entitySet),
323 | _typeMapper.GetTypeName(entitySet.ElementType));
324 | }
325 |
326 | public string UsingDirectives(bool inHeader, bool includeCollections = true)
327 | {
328 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
329 | ? string.Format(
330 | CultureInfo.InvariantCulture,
331 | "{0}using System;{1}" +
332 | "{2}",
333 | inHeader ? Environment.NewLine : "",
334 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
335 | inHeader ? "" : Environment.NewLine)
336 | : "";
337 | }
338 | }
339 |
340 | public class TypeMapper
341 | {
342 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
343 |
344 | private readonly System.Collections.IList _errors;
345 | private readonly CodeGenerationTools _code;
346 | private readonly MetadataTools _ef;
347 |
348 | public static string FixNamespaces(string typeName)
349 | {
350 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
351 | }
352 |
353 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
354 | {
355 | ArgumentNotNull(code, "code");
356 | ArgumentNotNull(ef, "ef");
357 | ArgumentNotNull(errors, "errors");
358 |
359 | _code = code;
360 | _ef = ef;
361 | _errors = errors;
362 | }
363 |
364 | public string GetTypeName(TypeUsage typeUsage)
365 | {
366 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
367 | }
368 |
369 | public string GetTypeName(EdmType edmType)
370 | {
371 | return GetTypeName(edmType, isNullable: null, modelNamespace: null);
372 | }
373 |
374 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
375 | {
376 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
377 | }
378 |
379 | public string GetTypeName(EdmType edmType, string modelNamespace)
380 | {
381 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
382 | }
383 |
384 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
385 | {
386 | if (edmType == null)
387 | {
388 | return null;
389 | }
390 |
391 | var collectionType = edmType as CollectionType;
392 | if (collectionType != null)
393 | {
394 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
395 | }
396 |
397 | var typeName = _code.Escape(edmType.MetadataProperties
398 | .Where(p => p.Name == ExternalTypeNameAttributeName)
399 | .Select(p => (string)p.Value)
400 | .FirstOrDefault())
401 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
402 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
403 | _code.Escape(edmType));
404 |
405 | if (edmType is StructuralType)
406 | {
407 | return typeName;
408 | }
409 |
410 | if (edmType is SimpleType)
411 | {
412 | var clrType = UnderlyingClrType(edmType);
413 | if (!IsEnumType(edmType))
414 | {
415 | typeName = _code.Escape(clrType);
416 | }
417 |
418 | typeName = FixNamespaces(typeName);
419 |
420 | return clrType.IsValueType && isNullable == true ?
421 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
422 | typeName;
423 | }
424 |
425 | throw new ArgumentException("edmType");
426 | }
427 |
428 | public Type UnderlyingClrType(EdmType edmType)
429 | {
430 | ArgumentNotNull(edmType, "edmType");
431 |
432 | var primitiveType = edmType as PrimitiveType;
433 | if (primitiveType != null)
434 | {
435 | return primitiveType.ClrEquivalentType;
436 | }
437 |
438 | if (IsEnumType(edmType))
439 | {
440 | return GetEnumUnderlyingType(edmType).ClrEquivalentType;
441 | }
442 |
443 | return typeof(object);
444 | }
445 |
446 | public object GetEnumMemberValue(MetadataItem enumMember)
447 | {
448 | ArgumentNotNull(enumMember, "enumMember");
449 |
450 | var valueProperty = enumMember.GetType().GetProperty("Value");
451 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
452 | }
453 |
454 | public string GetEnumMemberName(MetadataItem enumMember)
455 | {
456 | ArgumentNotNull(enumMember, "enumMember");
457 |
458 | var nameProperty = enumMember.GetType().GetProperty("Name");
459 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
460 | }
461 |
462 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
463 | {
464 | ArgumentNotNull(enumType, "enumType");
465 |
466 | var membersProperty = enumType.GetType().GetProperty("Members");
467 | return membersProperty != null
468 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
469 | : Enumerable.Empty();
470 | }
471 |
472 | public bool EnumIsFlags(EdmType enumType)
473 | {
474 | ArgumentNotNull(enumType, "enumType");
475 |
476 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
477 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
478 | }
479 |
480 | public bool IsEnumType(GlobalItem edmType)
481 | {
482 | ArgumentNotNull(edmType, "edmType");
483 |
484 | return edmType.GetType().Name == "EnumType";
485 | }
486 |
487 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
488 | {
489 | ArgumentNotNull(enumType, "enumType");
490 |
491 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
492 | }
493 |
494 | public string CreateLiteral(object value)
495 | {
496 | if (value == null || value.GetType() != typeof(TimeSpan))
497 | {
498 | return _code.CreateLiteral(value);
499 | }
500 |
501 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
502 | }
503 |
504 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
505 | {
506 | ArgumentNotNull(types, "types");
507 | ArgumentNotNull(sourceFile, "sourceFile");
508 |
509 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
510 | if (types.Any(item => !hash.Add(item)))
511 | {
512 | _errors.Add(
513 | new CompilerError(sourceFile, -1, -1, "6023",
514 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
515 | return false;
516 | }
517 | return true;
518 | }
519 |
520 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
521 | {
522 | return GetItemsToGenerate(itemCollection)
523 | .Where(e => IsEnumType(e));
524 | }
525 |
526 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
527 | {
528 | return itemCollection
529 | .OfType()
530 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
531 | .OrderBy(i => i.Name);
532 | }
533 |
534 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
535 | {
536 | return itemCollection
537 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
538 | .Select(g => GetGlobalItemName(g));
539 | }
540 |
541 | public string GetGlobalItemName(GlobalItem item)
542 | {
543 | if (item is EdmType)
544 | {
545 | return ((EdmType)item).Name;
546 | }
547 | else
548 | {
549 | return ((EntityContainer)item).Name;
550 | }
551 | }
552 |
553 | public IEnumerable GetSimpleProperties(EntityType type)
554 | {
555 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
556 | }
557 |
558 | public IEnumerable GetSimpleProperties(ComplexType type)
559 | {
560 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
561 | }
562 |
563 | public IEnumerable GetComplexProperties(EntityType type)
564 | {
565 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
566 | }
567 |
568 | public IEnumerable GetComplexProperties(ComplexType type)
569 | {
570 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
571 | }
572 |
573 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
574 | {
575 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
576 | }
577 |
578 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
579 | {
580 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
581 | }
582 |
583 | public IEnumerable GetNavigationProperties(EntityType type)
584 | {
585 | return type.NavigationProperties.Where(np => np.DeclaringType == type);
586 | }
587 |
588 | public IEnumerable GetCollectionNavigationProperties(EntityType type)
589 | {
590 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
591 | }
592 |
593 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
594 | {
595 | ArgumentNotNull(edmFunction, "edmFunction");
596 |
597 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
598 | return returnParamsProperty == null
599 | ? edmFunction.ReturnParameter
600 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
601 | }
602 |
603 | public bool IsComposable(EdmFunction edmFunction)
604 | {
605 | ArgumentNotNull(edmFunction, "edmFunction");
606 |
607 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
608 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
609 | }
610 |
611 | public IEnumerable GetParameters(EdmFunction edmFunction)
612 | {
613 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
614 | }
615 |
616 | public TypeUsage GetReturnType(EdmFunction edmFunction)
617 | {
618 | var returnParam = GetReturnParameter(edmFunction);
619 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
620 | }
621 |
622 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
623 | {
624 | var returnType = GetReturnType(edmFunction);
625 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
626 | }
627 | }
628 |
629 | public static void ArgumentNotNull(T arg, string name) where T : class
630 | {
631 | if (arg == null)
632 | {
633 | throw new ArgumentNullException(name);
634 | }
635 | }
636 | #>
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/NorthwindModel.Context.tt:
--------------------------------------------------------------------------------
1 | <#@ template language="C#" debug="false" hostspecific="true"#>
2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@
3 | output extension=".cs"#><#
4 |
5 | const string inputFile = @"NorthwindModel.edmx";
6 | var textTransform = DynamicTextTransformation.Create(this);
7 | var code = new CodeGenerationTools(this);
8 | var ef = new MetadataTools(this);
9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10 | var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
11 | var itemCollection = loader.CreateEdmItemCollection(inputFile);
12 | var modelNamespace = loader.GetModelNamespace(inputFile);
13 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
14 |
15 | var container = itemCollection.OfType().FirstOrDefault();
16 | if (container == null)
17 | {
18 | return string.Empty;
19 | }
20 | #>
21 | //------------------------------------------------------------------------------
22 | //
23 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
24 | //
25 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
26 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
27 | //
28 | //------------------------------------------------------------------------------
29 |
30 | <#
31 |
32 | var codeNamespace = code.VsNamespaceSuggestion();
33 | if (!String.IsNullOrEmpty(codeNamespace))
34 | {
35 | #>
36 | namespace <#=code.EscapeNamespace(codeNamespace)#>
37 | {
38 | <#
39 | PushIndent(" ");
40 | }
41 |
42 | #>
43 | using System;
44 | using System.Data.Entity;
45 | using System.Data.Entity.Infrastructure;
46 | <#
47 | if (container.FunctionImports.Any())
48 | {
49 | #>
50 | using System.Data.Entity.Core.Objects;
51 | using System.Linq;
52 | <#
53 | }
54 | #>
55 |
56 | <#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
57 | {
58 | public <#=code.Escape(container)#>()
59 | : base("name=<#=container.Name#>")
60 | {
61 | <#
62 | if (!loader.IsLazyLoadingEnabled(container))
63 | {
64 | #>
65 | this.Configuration.LazyLoadingEnabled = false;
66 | <#
67 | }
68 |
69 | foreach (var entitySet in container.BaseEntitySets.OfType())
70 | {
71 | // Note: the DbSet members are defined below such that the getter and
72 | // setter always have the same accessibility as the DbSet definition
73 | if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
74 | {
75 | #>
76 | <#=codeStringGenerator.DbSetInitializer(entitySet)#>
77 | <#
78 | }
79 | }
80 | #>
81 | }
82 |
83 | protected override void OnModelCreating(DbModelBuilder modelBuilder)
84 | {
85 | throw new UnintentionalCodeFirstException();
86 | }
87 |
88 | <#
89 | foreach (var entitySet in container.BaseEntitySets.OfType())
90 | {
91 | #>
92 | <#=codeStringGenerator.DbSet(entitySet)#>
93 | <#
94 | }
95 |
96 | foreach (var edmFunction in container.FunctionImports)
97 | {
98 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
99 | }
100 | #>
101 | }
102 | <#
103 |
104 | if (!String.IsNullOrEmpty(codeNamespace))
105 | {
106 | PopIndent();
107 | #>
108 | }
109 | <#
110 | }
111 | #>
112 | <#+
113 |
114 | private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
115 | {
116 | if (typeMapper.IsComposable(edmFunction))
117 | {
118 | #>
119 |
120 | [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
121 | <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
122 | {
123 | <#+
124 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
125 | #>
126 | <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
127 | }
128 | <#+
129 | }
130 | else
131 | {
132 | #>
133 |
134 | <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
135 | {
136 | <#+
137 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
138 | #>
139 | <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
140 | }
141 | <#+
142 | if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
143 | {
144 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
145 | }
146 | }
147 | }
148 |
149 | public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
150 | {
151 | #>
152 | var <#=name#> = <#=isNotNull#> ?
153 | <#=notNullInit#> :
154 | <#=nullInit#>;
155 |
156 | <#+
157 | }
158 |
159 | public const string TemplateId = "CSharp_DbContext_Context_EF6";
160 |
161 | public class CodeStringGenerator
162 | {
163 | private readonly CodeGenerationTools _code;
164 | private readonly TypeMapper _typeMapper;
165 | private readonly MetadataTools _ef;
166 |
167 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
168 | {
169 | ArgumentNotNull(code, "code");
170 | ArgumentNotNull(typeMapper, "typeMapper");
171 | ArgumentNotNull(ef, "ef");
172 |
173 | _code = code;
174 | _typeMapper = typeMapper;
175 | _ef = ef;
176 | }
177 |
178 | public string Property(EdmProperty edmProperty)
179 | {
180 | return string.Format(
181 | CultureInfo.InvariantCulture,
182 | "{0} {1} {2} {{ {3}get; {4}set; }}",
183 | Accessibility.ForProperty(edmProperty),
184 | _typeMapper.GetTypeName(edmProperty.TypeUsage),
185 | _code.Escape(edmProperty),
186 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
187 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
188 | }
189 |
190 | public string NavigationProperty(NavigationProperty navProp)
191 | {
192 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
193 | return string.Format(
194 | CultureInfo.InvariantCulture,
195 | "{0} {1} {2} {{ {3}get; {4}set; }}",
196 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
197 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
198 | _code.Escape(navProp),
199 | _code.SpaceAfter(Accessibility.ForGetter(navProp)),
200 | _code.SpaceAfter(Accessibility.ForSetter(navProp)));
201 | }
202 |
203 | public string AccessibilityAndVirtual(string accessibility)
204 | {
205 | return accessibility + (accessibility != "private" ? " virtual" : "");
206 | }
207 |
208 | public string EntityClassOpening(EntityType entity)
209 | {
210 | return string.Format(
211 | CultureInfo.InvariantCulture,
212 | "{0} {1}partial class {2}{3}",
213 | Accessibility.ForType(entity),
214 | _code.SpaceAfter(_code.AbstractOption(entity)),
215 | _code.Escape(entity),
216 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
217 | }
218 |
219 | public string EnumOpening(SimpleType enumType)
220 | {
221 | return string.Format(
222 | CultureInfo.InvariantCulture,
223 | "{0} enum {1} : {2}",
224 | Accessibility.ForType(enumType),
225 | _code.Escape(enumType),
226 | _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
227 | }
228 |
229 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
230 | {
231 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
232 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
233 | {
234 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
235 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
236 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
237 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
238 | }
239 | }
240 |
241 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
242 | {
243 | var parameters = _typeMapper.GetParameters(edmFunction);
244 |
245 | return string.Format(
246 | CultureInfo.InvariantCulture,
247 | "{0} IQueryable<{1}> {2}({3})",
248 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
249 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
250 | _code.Escape(edmFunction),
251 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
252 | }
253 |
254 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
255 | {
256 | var parameters = _typeMapper.GetParameters(edmFunction);
257 |
258 | return string.Format(
259 | CultureInfo.InvariantCulture,
260 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
261 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
262 | edmFunction.NamespaceName,
263 | edmFunction.Name,
264 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
265 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
266 | }
267 |
268 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
269 | {
270 | var parameters = _typeMapper.GetParameters(edmFunction);
271 | var returnType = _typeMapper.GetReturnType(edmFunction);
272 |
273 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
274 | if (includeMergeOption)
275 | {
276 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
277 | }
278 |
279 | return string.Format(
280 | CultureInfo.InvariantCulture,
281 | "{0} {1} {2}({3})",
282 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
283 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
284 | _code.Escape(edmFunction),
285 | paramList);
286 | }
287 |
288 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
289 | {
290 | var parameters = _typeMapper.GetParameters(edmFunction);
291 | var returnType = _typeMapper.GetReturnType(edmFunction);
292 |
293 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
294 | if (includeMergeOption)
295 | {
296 | callParams = ", mergeOption" + callParams;
297 | }
298 |
299 | return string.Format(
300 | CultureInfo.InvariantCulture,
301 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
302 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
303 | edmFunction.Name,
304 | callParams);
305 | }
306 |
307 | public string DbSet(EntitySet entitySet)
308 | {
309 | return string.Format(
310 | CultureInfo.InvariantCulture,
311 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
312 | Accessibility.ForReadOnlyProperty(entitySet),
313 | _typeMapper.GetTypeName(entitySet.ElementType),
314 | _code.Escape(entitySet));
315 | }
316 |
317 | public string DbSetInitializer(EntitySet entitySet)
318 | {
319 | return string.Format(
320 | CultureInfo.InvariantCulture,
321 | "{0} = Set<{1}>();",
322 | _code.Escape(entitySet),
323 | _typeMapper.GetTypeName(entitySet.ElementType));
324 | }
325 |
326 | public string UsingDirectives(bool inHeader, bool includeCollections = true)
327 | {
328 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
329 | ? string.Format(
330 | CultureInfo.InvariantCulture,
331 | "{0}using System;{1}" +
332 | "{2}",
333 | inHeader ? Environment.NewLine : "",
334 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
335 | inHeader ? "" : Environment.NewLine)
336 | : "";
337 | }
338 | }
339 |
340 | public class TypeMapper
341 | {
342 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
343 |
344 | private readonly System.Collections.IList _errors;
345 | private readonly CodeGenerationTools _code;
346 | private readonly MetadataTools _ef;
347 |
348 | public static string FixNamespaces(string typeName)
349 | {
350 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
351 | }
352 |
353 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
354 | {
355 | ArgumentNotNull(code, "code");
356 | ArgumentNotNull(ef, "ef");
357 | ArgumentNotNull(errors, "errors");
358 |
359 | _code = code;
360 | _ef = ef;
361 | _errors = errors;
362 | }
363 |
364 | public string GetTypeName(TypeUsage typeUsage)
365 | {
366 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
367 | }
368 |
369 | public string GetTypeName(EdmType edmType)
370 | {
371 | return GetTypeName(edmType, isNullable: null, modelNamespace: null);
372 | }
373 |
374 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
375 | {
376 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
377 | }
378 |
379 | public string GetTypeName(EdmType edmType, string modelNamespace)
380 | {
381 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
382 | }
383 |
384 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
385 | {
386 | if (edmType == null)
387 | {
388 | return null;
389 | }
390 |
391 | var collectionType = edmType as CollectionType;
392 | if (collectionType != null)
393 | {
394 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
395 | }
396 |
397 | var typeName = _code.Escape(edmType.MetadataProperties
398 | .Where(p => p.Name == ExternalTypeNameAttributeName)
399 | .Select(p => (string)p.Value)
400 | .FirstOrDefault())
401 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
402 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
403 | _code.Escape(edmType));
404 |
405 | if (edmType is StructuralType)
406 | {
407 | return typeName;
408 | }
409 |
410 | if (edmType is SimpleType)
411 | {
412 | var clrType = UnderlyingClrType(edmType);
413 | if (!IsEnumType(edmType))
414 | {
415 | typeName = _code.Escape(clrType);
416 | }
417 |
418 | typeName = FixNamespaces(typeName);
419 |
420 | return clrType.IsValueType && isNullable == true ?
421 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
422 | typeName;
423 | }
424 |
425 | throw new ArgumentException("edmType");
426 | }
427 |
428 | public Type UnderlyingClrType(EdmType edmType)
429 | {
430 | ArgumentNotNull(edmType, "edmType");
431 |
432 | var primitiveType = edmType as PrimitiveType;
433 | if (primitiveType != null)
434 | {
435 | return primitiveType.ClrEquivalentType;
436 | }
437 |
438 | if (IsEnumType(edmType))
439 | {
440 | return GetEnumUnderlyingType(edmType).ClrEquivalentType;
441 | }
442 |
443 | return typeof(object);
444 | }
445 |
446 | public object GetEnumMemberValue(MetadataItem enumMember)
447 | {
448 | ArgumentNotNull(enumMember, "enumMember");
449 |
450 | var valueProperty = enumMember.GetType().GetProperty("Value");
451 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
452 | }
453 |
454 | public string GetEnumMemberName(MetadataItem enumMember)
455 | {
456 | ArgumentNotNull(enumMember, "enumMember");
457 |
458 | var nameProperty = enumMember.GetType().GetProperty("Name");
459 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
460 | }
461 |
462 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
463 | {
464 | ArgumentNotNull(enumType, "enumType");
465 |
466 | var membersProperty = enumType.GetType().GetProperty("Members");
467 | return membersProperty != null
468 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
469 | : Enumerable.Empty();
470 | }
471 |
472 | public bool EnumIsFlags(EdmType enumType)
473 | {
474 | ArgumentNotNull(enumType, "enumType");
475 |
476 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
477 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
478 | }
479 |
480 | public bool IsEnumType(GlobalItem edmType)
481 | {
482 | ArgumentNotNull(edmType, "edmType");
483 |
484 | return edmType.GetType().Name == "EnumType";
485 | }
486 |
487 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
488 | {
489 | ArgumentNotNull(enumType, "enumType");
490 |
491 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
492 | }
493 |
494 | public string CreateLiteral(object value)
495 | {
496 | if (value == null || value.GetType() != typeof(TimeSpan))
497 | {
498 | return _code.CreateLiteral(value);
499 | }
500 |
501 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
502 | }
503 |
504 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
505 | {
506 | ArgumentNotNull(types, "types");
507 | ArgumentNotNull(sourceFile, "sourceFile");
508 |
509 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
510 | if (types.Any(item => !hash.Add(item)))
511 | {
512 | _errors.Add(
513 | new CompilerError(sourceFile, -1, -1, "6023",
514 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
515 | return false;
516 | }
517 | return true;
518 | }
519 |
520 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
521 | {
522 | return GetItemsToGenerate(itemCollection)
523 | .Where(e => IsEnumType(e));
524 | }
525 |
526 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
527 | {
528 | return itemCollection
529 | .OfType()
530 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
531 | .OrderBy(i => i.Name);
532 | }
533 |
534 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
535 | {
536 | return itemCollection
537 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
538 | .Select(g => GetGlobalItemName(g));
539 | }
540 |
541 | public string GetGlobalItemName(GlobalItem item)
542 | {
543 | if (item is EdmType)
544 | {
545 | return ((EdmType)item).Name;
546 | }
547 | else
548 | {
549 | return ((EntityContainer)item).Name;
550 | }
551 | }
552 |
553 | public IEnumerable GetSimpleProperties(EntityType type)
554 | {
555 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
556 | }
557 |
558 | public IEnumerable GetSimpleProperties(ComplexType type)
559 | {
560 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
561 | }
562 |
563 | public IEnumerable GetComplexProperties(EntityType type)
564 | {
565 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
566 | }
567 |
568 | public IEnumerable GetComplexProperties(ComplexType type)
569 | {
570 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
571 | }
572 |
573 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
574 | {
575 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
576 | }
577 |
578 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
579 | {
580 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
581 | }
582 |
583 | public IEnumerable GetNavigationProperties(EntityType type)
584 | {
585 | return type.NavigationProperties.Where(np => np.DeclaringType == type);
586 | }
587 |
588 | public IEnumerable GetCollectionNavigationProperties(EntityType type)
589 | {
590 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
591 | }
592 |
593 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
594 | {
595 | ArgumentNotNull(edmFunction, "edmFunction");
596 |
597 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
598 | return returnParamsProperty == null
599 | ? edmFunction.ReturnParameter
600 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
601 | }
602 |
603 | public bool IsComposable(EdmFunction edmFunction)
604 | {
605 | ArgumentNotNull(edmFunction, "edmFunction");
606 |
607 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
608 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
609 | }
610 |
611 | public IEnumerable GetParameters(EdmFunction edmFunction)
612 | {
613 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
614 | }
615 |
616 | public TypeUsage GetReturnType(EdmFunction edmFunction)
617 | {
618 | var returnParam = GetReturnParameter(edmFunction);
619 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
620 | }
621 |
622 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
623 | {
624 | var returnType = GetReturnType(edmFunction);
625 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
626 | }
627 | }
628 |
629 | public static void ArgumentNotNull(T arg, string name) where T : class
630 | {
631 | if (arg == null)
632 | {
633 | throw new ArgumentNullException(name);
634 | }
635 | }
636 | #>
--------------------------------------------------------------------------------
/source/VisualStudio/ConsoleForEF/ToursModel.tt:
--------------------------------------------------------------------------------
1 | <#@ template language="C#" debug="false" hostspecific="true"#>
2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@
3 | output extension=".cs"#><#
4 |
5 | const string inputFile = @"ToursModel.edmx";
6 | var textTransform = DynamicTextTransformation.Create(this);
7 | var code = new CodeGenerationTools(this);
8 | var ef = new MetadataTools(this);
9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10 | var fileManager = EntityFrameworkTemplateFileManager.Create(this);
11 | var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
12 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
13 |
14 | if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
15 | {
16 | return string.Empty;
17 | }
18 |
19 | WriteHeader(codeStringGenerator, fileManager);
20 |
21 | foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection))
22 | {
23 | fileManager.StartNewFile(entity.Name + ".cs");
24 | BeginNamespace(code);
25 | #>
26 | <#=codeStringGenerator.UsingDirectives(inHeader: false)#>
27 | <#=codeStringGenerator.EntityClassOpening(entity)#>
28 | {
29 | <#
30 | var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
31 | var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
32 | var complexProperties = typeMapper.GetComplexProperties(entity);
33 |
34 | if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
35 | {
36 | #>
37 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
38 | public <#=code.Escape(entity)#>()
39 | {
40 | <#
41 | foreach (var edmProperty in propertiesWithDefaultValues)
42 | {
43 | #>
44 | this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
45 | <#
46 | }
47 |
48 | foreach (var navigationProperty in collectionNavigationProperties)
49 | {
50 | #>
51 | this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
52 | <#
53 | }
54 |
55 | foreach (var complexProperty in complexProperties)
56 | {
57 | #>
58 | this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
59 | <#
60 | }
61 | #>
62 | }
63 |
64 | <#
65 | }
66 |
67 | var simpleProperties = typeMapper.GetSimpleProperties(entity);
68 | if (simpleProperties.Any())
69 | {
70 | foreach (var edmProperty in simpleProperties)
71 | {
72 | #>
73 | <#=codeStringGenerator.Property(edmProperty)#>
74 | <#
75 | }
76 | }
77 |
78 | if (complexProperties.Any())
79 | {
80 | #>
81 |
82 | <#
83 | foreach(var complexProperty in complexProperties)
84 | {
85 | #>
86 | <#=codeStringGenerator.Property(complexProperty)#>
87 | <#
88 | }
89 | }
90 |
91 | var navigationProperties = typeMapper.GetNavigationProperties(entity);
92 | if (navigationProperties.Any())
93 | {
94 | #>
95 |
96 | <#
97 | foreach (var navigationProperty in navigationProperties)
98 | {
99 | if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
100 | {
101 | #>
102 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
103 | <#
104 | }
105 | #>
106 | <#=codeStringGenerator.NavigationProperty(navigationProperty)#>
107 | <#
108 | }
109 | }
110 | #>
111 | }
112 | <#
113 | EndNamespace(code);
114 | }
115 |
116 | foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection))
117 | {
118 | fileManager.StartNewFile(complex.Name + ".cs");
119 | BeginNamespace(code);
120 | #>
121 | <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
122 | <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
123 | {
124 | <#
125 | var complexProperties = typeMapper.GetComplexProperties(complex);
126 | var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
127 |
128 | if (propertiesWithDefaultValues.Any() || complexProperties.Any())
129 | {
130 | #>
131 | public <#=code.Escape(complex)#>()
132 | {
133 | <#
134 | foreach (var edmProperty in propertiesWithDefaultValues)
135 | {
136 | #>
137 | this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
138 | <#
139 | }
140 |
141 | foreach (var complexProperty in complexProperties)
142 | {
143 | #>
144 | this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
145 | <#
146 | }
147 | #>
148 | }
149 |
150 | <#
151 | }
152 |
153 | var simpleProperties = typeMapper.GetSimpleProperties(complex);
154 | if (simpleProperties.Any())
155 | {
156 | foreach(var edmProperty in simpleProperties)
157 | {
158 | #>
159 | <#=codeStringGenerator.Property(edmProperty)#>
160 | <#
161 | }
162 | }
163 |
164 | if (complexProperties.Any())
165 | {
166 | #>
167 |
168 | <#
169 | foreach(var edmProperty in complexProperties)
170 | {
171 | #>
172 | <#=codeStringGenerator.Property(edmProperty)#>
173 | <#
174 | }
175 | }
176 | #>
177 | }
178 | <#
179 | EndNamespace(code);
180 | }
181 |
182 | foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
183 | {
184 | fileManager.StartNewFile(enumType.Name + ".cs");
185 | BeginNamespace(code);
186 | #>
187 | <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
188 | <#
189 | if (typeMapper.EnumIsFlags(enumType))
190 | {
191 | #>
192 | [Flags]
193 | <#
194 | }
195 | #>
196 | <#=codeStringGenerator.EnumOpening(enumType)#>
197 | {
198 | <#
199 | var foundOne = false;
200 |
201 | foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
202 | {
203 | foundOne = true;
204 | #>
205 | <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
206 | <#
207 | }
208 |
209 | if (foundOne)
210 | {
211 | this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
212 | }
213 | #>
214 | }
215 | <#
216 | EndNamespace(code);
217 | }
218 |
219 | fileManager.Process();
220 |
221 | #>
222 | <#+
223 |
224 | public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
225 | {
226 | fileManager.StartHeader();
227 | #>
228 | //------------------------------------------------------------------------------
229 | //
230 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
231 | //
232 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
233 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
234 | //
235 | //------------------------------------------------------------------------------
236 | <#=codeStringGenerator.UsingDirectives(inHeader: true)#>
237 | <#+
238 | fileManager.EndBlock();
239 | }
240 |
241 | public void BeginNamespace(CodeGenerationTools code)
242 | {
243 | var codeNamespace = code.VsNamespaceSuggestion();
244 | if (!String.IsNullOrEmpty(codeNamespace))
245 | {
246 | #>
247 | namespace <#=code.EscapeNamespace(codeNamespace)#>
248 | {
249 | <#+
250 | PushIndent(" ");
251 | }
252 | }
253 |
254 | public void EndNamespace(CodeGenerationTools code)
255 | {
256 | if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
257 | {
258 | PopIndent();
259 | #>
260 | }
261 | <#+
262 | }
263 | }
264 |
265 | public const string TemplateId = "CSharp_DbContext_Types_EF6";
266 |
267 | public class CodeStringGenerator
268 | {
269 | private readonly CodeGenerationTools _code;
270 | private readonly TypeMapper _typeMapper;
271 | private readonly MetadataTools _ef;
272 |
273 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
274 | {
275 | ArgumentNotNull(code, "code");
276 | ArgumentNotNull(typeMapper, "typeMapper");
277 | ArgumentNotNull(ef, "ef");
278 |
279 | _code = code;
280 | _typeMapper = typeMapper;
281 | _ef = ef;
282 | }
283 |
284 | public string Property(EdmProperty edmProperty)
285 | {
286 | return string.Format(
287 | CultureInfo.InvariantCulture,
288 | "{0} {1} {2} {{ {3}get; {4}set; }}",
289 | Accessibility.ForProperty(edmProperty),
290 | _typeMapper.GetTypeName(edmProperty.TypeUsage),
291 | _code.Escape(edmProperty),
292 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
293 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
294 | }
295 |
296 | public string NavigationProperty(NavigationProperty navProp)
297 | {
298 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
299 | return string.Format(
300 | CultureInfo.InvariantCulture,
301 | "{0} {1} {2} {{ {3}get; {4}set; }}",
302 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
303 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
304 | _code.Escape(navProp),
305 | _code.SpaceAfter(Accessibility.ForGetter(navProp)),
306 | _code.SpaceAfter(Accessibility.ForSetter(navProp)));
307 | }
308 |
309 | public string AccessibilityAndVirtual(string accessibility)
310 | {
311 | return accessibility + (accessibility != "private" ? " virtual" : "");
312 | }
313 |
314 | public string EntityClassOpening(EntityType entity)
315 | {
316 | return string.Format(
317 | CultureInfo.InvariantCulture,
318 | "{0} {1}partial class {2}{3}",
319 | Accessibility.ForType(entity),
320 | _code.SpaceAfter(_code.AbstractOption(entity)),
321 | _code.Escape(entity),
322 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
323 | }
324 |
325 | public string EnumOpening(SimpleType enumType)
326 | {
327 | return string.Format(
328 | CultureInfo.InvariantCulture,
329 | "{0} enum {1} : {2}",
330 | Accessibility.ForType(enumType),
331 | _code.Escape(enumType),
332 | _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
333 | }
334 |
335 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
336 | {
337 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
338 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
339 | {
340 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
341 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
342 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
343 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
344 | }
345 | }
346 |
347 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
348 | {
349 | var parameters = _typeMapper.GetParameters(edmFunction);
350 |
351 | return string.Format(
352 | CultureInfo.InvariantCulture,
353 | "{0} IQueryable<{1}> {2}({3})",
354 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
355 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
356 | _code.Escape(edmFunction),
357 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
358 | }
359 |
360 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
361 | {
362 | var parameters = _typeMapper.GetParameters(edmFunction);
363 |
364 | return string.Format(
365 | CultureInfo.InvariantCulture,
366 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
367 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
368 | edmFunction.NamespaceName,
369 | edmFunction.Name,
370 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
371 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
372 | }
373 |
374 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
375 | {
376 | var parameters = _typeMapper.GetParameters(edmFunction);
377 | var returnType = _typeMapper.GetReturnType(edmFunction);
378 |
379 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
380 | if (includeMergeOption)
381 | {
382 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
383 | }
384 |
385 | return string.Format(
386 | CultureInfo.InvariantCulture,
387 | "{0} {1} {2}({3})",
388 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
389 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
390 | _code.Escape(edmFunction),
391 | paramList);
392 | }
393 |
394 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
395 | {
396 | var parameters = _typeMapper.GetParameters(edmFunction);
397 | var returnType = _typeMapper.GetReturnType(edmFunction);
398 |
399 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
400 | if (includeMergeOption)
401 | {
402 | callParams = ", mergeOption" + callParams;
403 | }
404 |
405 | return string.Format(
406 | CultureInfo.InvariantCulture,
407 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
408 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
409 | edmFunction.Name,
410 | callParams);
411 | }
412 |
413 | public string DbSet(EntitySet entitySet)
414 | {
415 | return string.Format(
416 | CultureInfo.InvariantCulture,
417 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
418 | Accessibility.ForReadOnlyProperty(entitySet),
419 | _typeMapper.GetTypeName(entitySet.ElementType),
420 | _code.Escape(entitySet));
421 | }
422 |
423 | public string UsingDirectives(bool inHeader, bool includeCollections = true)
424 | {
425 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
426 | ? string.Format(
427 | CultureInfo.InvariantCulture,
428 | "{0}using System;{1}" +
429 | "{2}",
430 | inHeader ? Environment.NewLine : "",
431 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
432 | inHeader ? "" : Environment.NewLine)
433 | : "";
434 | }
435 | }
436 |
437 | public class TypeMapper
438 | {
439 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
440 |
441 | private readonly System.Collections.IList _errors;
442 | private readonly CodeGenerationTools _code;
443 | private readonly MetadataTools _ef;
444 |
445 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
446 | {
447 | ArgumentNotNull(code, "code");
448 | ArgumentNotNull(ef, "ef");
449 | ArgumentNotNull(errors, "errors");
450 |
451 | _code = code;
452 | _ef = ef;
453 | _errors = errors;
454 | }
455 |
456 | public static string FixNamespaces(string typeName)
457 | {
458 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
459 | }
460 |
461 | public string GetTypeName(TypeUsage typeUsage)
462 | {
463 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
464 | }
465 |
466 | public string GetTypeName(EdmType edmType)
467 | {
468 | return GetTypeName(edmType, isNullable: null, modelNamespace: null);
469 | }
470 |
471 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
472 | {
473 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
474 | }
475 |
476 | public string GetTypeName(EdmType edmType, string modelNamespace)
477 | {
478 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
479 | }
480 |
481 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
482 | {
483 | if (edmType == null)
484 | {
485 | return null;
486 | }
487 |
488 | var collectionType = edmType as CollectionType;
489 | if (collectionType != null)
490 | {
491 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
492 | }
493 |
494 | var typeName = _code.Escape(edmType.MetadataProperties
495 | .Where(p => p.Name == ExternalTypeNameAttributeName)
496 | .Select(p => (string)p.Value)
497 | .FirstOrDefault())
498 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
499 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
500 | _code.Escape(edmType));
501 |
502 | if (edmType is StructuralType)
503 | {
504 | return typeName;
505 | }
506 |
507 | if (edmType is SimpleType)
508 | {
509 | var clrType = UnderlyingClrType(edmType);
510 | if (!IsEnumType(edmType))
511 | {
512 | typeName = _code.Escape(clrType);
513 | }
514 |
515 | typeName = FixNamespaces(typeName);
516 |
517 | return clrType.IsValueType && isNullable == true ?
518 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
519 | typeName;
520 | }
521 |
522 | throw new ArgumentException("edmType");
523 | }
524 |
525 | public Type UnderlyingClrType(EdmType edmType)
526 | {
527 | ArgumentNotNull(edmType, "edmType");
528 |
529 | var primitiveType = edmType as PrimitiveType;
530 | if (primitiveType != null)
531 | {
532 | return primitiveType.ClrEquivalentType;
533 | }
534 |
535 | if (IsEnumType(edmType))
536 | {
537 | return GetEnumUnderlyingType(edmType).ClrEquivalentType;
538 | }
539 |
540 | return typeof(object);
541 | }
542 |
543 | public object GetEnumMemberValue(MetadataItem enumMember)
544 | {
545 | ArgumentNotNull(enumMember, "enumMember");
546 |
547 | var valueProperty = enumMember.GetType().GetProperty("Value");
548 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
549 | }
550 |
551 | public string GetEnumMemberName(MetadataItem enumMember)
552 | {
553 | ArgumentNotNull(enumMember, "enumMember");
554 |
555 | var nameProperty = enumMember.GetType().GetProperty("Name");
556 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
557 | }
558 |
559 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
560 | {
561 | ArgumentNotNull(enumType, "enumType");
562 |
563 | var membersProperty = enumType.GetType().GetProperty("Members");
564 | return membersProperty != null
565 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
566 | : Enumerable.Empty();
567 | }
568 |
569 | public bool EnumIsFlags(EdmType enumType)
570 | {
571 | ArgumentNotNull(enumType, "enumType");
572 |
573 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
574 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
575 | }
576 |
577 | public bool IsEnumType(GlobalItem edmType)
578 | {
579 | ArgumentNotNull(edmType, "edmType");
580 |
581 | return edmType.GetType().Name == "EnumType";
582 | }
583 |
584 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
585 | {
586 | ArgumentNotNull(enumType, "enumType");
587 |
588 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
589 | }
590 |
591 | public string CreateLiteral(object value)
592 | {
593 | if (value == null || value.GetType() != typeof(TimeSpan))
594 | {
595 | return _code.CreateLiteral(value);
596 | }
597 |
598 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
599 | }
600 |
601 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
602 | {
603 | ArgumentNotNull(types, "types");
604 | ArgumentNotNull(sourceFile, "sourceFile");
605 |
606 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
607 | if (types.Any(item => !hash.Add(item)))
608 | {
609 | _errors.Add(
610 | new CompilerError(sourceFile, -1, -1, "6023",
611 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
612 | return false;
613 | }
614 | return true;
615 | }
616 |
617 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
618 | {
619 | return GetItemsToGenerate(itemCollection)
620 | .Where(e => IsEnumType(e));
621 | }
622 |
623 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
624 | {
625 | return itemCollection
626 | .OfType()
627 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
628 | .OrderBy(i => i.Name);
629 | }
630 |
631 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
632 | {
633 | return itemCollection
634 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
635 | .Select(g => GetGlobalItemName(g));
636 | }
637 |
638 | public string GetGlobalItemName(GlobalItem item)
639 | {
640 | if (item is EdmType)
641 | {
642 | return ((EdmType)item).Name;
643 | }
644 | else
645 | {
646 | return ((EntityContainer)item).Name;
647 | }
648 | }
649 |
650 | public IEnumerable GetSimpleProperties(EntityType type)
651 | {
652 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
653 | }
654 |
655 | public IEnumerable GetSimpleProperties(ComplexType type)
656 | {
657 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
658 | }
659 |
660 | public IEnumerable GetComplexProperties(EntityType type)
661 | {
662 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
663 | }
664 |
665 | public IEnumerable GetComplexProperties(ComplexType type)
666 | {
667 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
668 | }
669 |
670 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
671 | {
672 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
673 | }
674 |
675 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
676 | {
677 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
678 | }
679 |
680 | public IEnumerable GetNavigationProperties(EntityType type)
681 | {
682 | return type.NavigationProperties.Where(np => np.DeclaringType == type);
683 | }
684 |
685 | public IEnumerable GetCollectionNavigationProperties(EntityType type)
686 | {
687 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
688 | }
689 |
690 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
691 | {
692 | ArgumentNotNull(edmFunction, "edmFunction");
693 |
694 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
695 | return returnParamsProperty == null
696 | ? edmFunction.ReturnParameter
697 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
698 | }
699 |
700 | public bool IsComposable(EdmFunction edmFunction)
701 | {
702 | ArgumentNotNull(edmFunction, "edmFunction");
703 |
704 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
705 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
706 | }
707 |
708 | public IEnumerable GetParameters(EdmFunction edmFunction)
709 | {
710 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
711 | }
712 |
713 | public TypeUsage GetReturnType(EdmFunction edmFunction)
714 | {
715 | var returnParam = GetReturnParameter(edmFunction);
716 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
717 | }
718 |
719 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
720 | {
721 | var returnType = GetReturnType(edmFunction);
722 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
723 | }
724 | }
725 |
726 | public static void ArgumentNotNull(T arg, string name) where T : class
727 | {
728 | if (arg == null)
729 | {
730 | throw new ArgumentNullException(name);
731 | }
732 | }
733 | #>
--------------------------------------------------------------------------------