ADO.Net Entity Framework Posts Related Posts by ThinqLinq

Hierarchical Trees from Flat Tables using LINQ

I’m often tasked with creating a tree representation of a structure from a flat self-referencing table. For example, in the EF extensions to Northwind, they extended the Employee table so that it has a self-referencing “ReportsTo” column. As you can see from the data below, Andrew Fuller does not report to any other employees, but Nancy, Janet, Margaret, Steven, and Laura all report to Andrew (because their ReportsTo value is the same as Andrew’s EmployeeID). Likewise Michael, Robert, and Anne all report to Steven.

image

In order to generate a tree representation of these records, we could start with any records that have no direct reports and then lazy load each of their children. Unfortunately for large graphs, the number of database hits will grow exponentially as we add tree levels. Typically with parent-child relationships, we could eager load the children using the DataLoadOptions with LINQ to SQL or .Includes with Entity Framework. However with self-referencing entities, this isn’t allowed. With LINQ to SQL, you will get an InvalidOperationException “Cycles not allowed in LoadOptions LoadWith type graph.”

So, how do we load the tree in one pass and build the object graphs? It’s really not that hard once you realize how reference types (classes) work in .Net. Let’s start by creating a holder for each employee and their associated direct reports:

Public Class HierarchicalEmployee
    Public Sub New(emp As Employee)
           Model = emp
    End Sub
    Public Property Model As Employee
    Public Property DirectReports As New List(Of HierarchicalEmployee)
End Class

Now that we have this type, we can fill it using a simple LINQ request. In order to optimize the next step, we’ll push the values into an in-memory Dictionary indexed by the EmployeeID:

Dim allEmployees = Employees.
    Select(Function(emp) New HierarchicalEmployee(emp)).
    ToDictionary(Function(emp) emp.Model.EmployeeID)

Next, we iterate over the full list. For records that have a ReportsTo value, we’ll add their object pointer to their parent’s DirectReports list:

For Each emp In allEmployees.Values
  If emp.Model.ReportsTo.HasValue Then
    allEmployees(emp.Model.ReportsTo.Value).DirectReports.Add(emp)
  End If
Next

Notice, here we take advantage of the Dictionary’s hash rather than having to iterate over the list each time we want to find the parent record. Finally, instead of returning the full list, we only return the employees that don’t have any children (where the ReportsTo is null).

 
Dim rootEmployees = allEmployees.Values.
    Where(function(emp) Not emp.Model.ReportsTo.HasValue())

If we want to test this out in LinqPad, just use the Dump method on the resulting rootEmployees. As a result, you’ll see the following in the results pane. Notice Andrew is the only root object. He has 5 direct reports and one of his reports had 3 reports. You could just as easily bind this to a treeview control or output it using your favorite UI tooling.

 

image

The nice thing about this solution is that if we check the generated SQL, we will just see a simple (single) SQL request to generate the entire graph. As a summary, here’s the complete code from the LinqPad sample:

 

Sub Main
    Dim allEmployees = Employees.
        Select(Function(emp) New HierarchicalEmployee(emp)).
        ToDictionary(Function(emp) emp.Model.EmployeeID)

    For Each emp In allEmployees.Values
        If emp.Model.ReportsTo.HasValue Then
            allEmployees(emp.Model.ReportsTo.Value).DirectReports.Add(emp)
        End If
    Next
    
    Dim rootEmployees = allEmployees.Values.
        Where(function(emp) Not emp.Model.ReportsTo.HasValue())
        
    
    rootEmployees.Dump
End Sub

Public Class HierarchicalEmployee
    Public Sub New(emp As Employee)
           Model = emp
    End Sub
    Public Property Model As Employee
    Public Property DirectReports As New List(Of HierarchicalEmployee)
End Class
Posted on - Comment
Categories: VB Dev Center - LINQ - Entity Framework -

Aggregate clause issues

I was reviewing a Stack Exchange message regarding the Aggregate clause in VB () where they found that the query was issuing multiple requests to the database and occasionally returning the entire database table to memory and using LINQ to Objects over the result. I also found that Frans Bouma blogged about this back in 2008 at  . Consider the following LINQ query over Northwind:

Dim query = Aggregate o in Orders
                   into Sum(o.Freight),
                   Average(o.Freight),
                   Max(o.Freight)

This produces the following TSQL Statements in EF. Notice here that the Sum and Avg are performed on the server, but the Max pulls the entire table to memory and does Max on the client. It would seem that this is an issue in the expression tree parser.

SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
   SUM([Extent1].[Freight]) AS [A1]
   FROM [dbo].[Orders] AS [Extent1]
)  AS [GroupBy1]

GO

SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
   AVG([Extent1].[Freight]) AS [A1]
   FROM [dbo].[Orders] AS [Extent1]
)  AS [GroupBy1]

GO

SELECT
[Extent1].[OrderID] AS [OrderID],
[Extent1].[CustomerID] AS [CustomerID],
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[OrderDate] AS [OrderDate],
[Extent1].[RequiredDate] AS [RequiredDate],
[Extent1].[ShippedDate] AS [ShippedDate],
[Extent1].[ShipVia] AS [ShipVia],
[Extent1].[Freight] AS [Freight],
[Extent1].[ShipName] AS [ShipName],
[Extent1].[ShipAddress] AS [ShipAddress],
[Extent1].[ShipCity] AS [ShipCity],
[Extent1].[ShipRegion] AS [ShipRegion],
[Extent1].[ShipPostalCode] AS [ShipPostalCode],
[Extent1].[ShipCountry] AS [ShipCountry]
FROM [dbo].[Orders] AS [Extent1]

For comparison, here’s the queries issued from LINQ to SQL:

SELECT SUM([t0].[Freight]) AS [value]
FROM [Orders] AS [t0]
GO

SELECT AVG([t0].[Freight]) AS [value]
FROM [Orders] AS [t0]
GO

SELECT [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], [t0].[RequiredDate], [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], [t0].[ShipName], [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], [t0].[ShipPostalCode], [t0].[ShipCountry]
FROM [Orders] AS [t0]

Interestingly, if you use From instead of Aggregate, the expression tree parsers seem to be able to handle this better. For example, the original query could be re-written as follows:

Dim query = From o in Orders
                  Group By key = 0
                  into Sum(o.Freight),
                  Average(o.Freight),
                  Max(o.Freight)

This produces the following SQL (using LINQ to SQL):

SELECT SUM([t1].[Freight]) AS [Sum], AVG([t1].[Freight]) AS [Average], MAX([t1].[Freight]) AS [Max]
FROM (
    SELECT @p0 AS [value], [t0].[Freight]
    FROM [Orders] AS [t0]
    ) AS [t1]
GROUP BY [t1].[value]

For the time being at least, I have to agree with Frans that it is best to avoid using the Aggregate keyword in VB when accessing a database. I’ll update this if I hear any updates that are on the horizon.

Posted on - Comment
Categories: VB Dev Center - LINQ - Entity Framework -

LINQ to Database Performance hints

Although I’ve been writing primarily about RX here for a while, I still dig into some good old LINQ to SQL / EF quite a bit. Along the way, I’m frequently finding more tidbits to throw in the toolbox and thought I’d share some observations from a recent performance tuning project. (I’ll avoid disclosing the client and will change the database model to Northwind for this discussion protect the guilty.)

In this project, I was brought in at the end of the project as things started going south to try to get it across the finish line. As with many projects, they waited until after the development was complete before they started to consider the performance impact of their code. This violates one of the principal tenants of performance testing:

RULE 1: Test early and often

Performance for larger scale apps needs to be considered from the beginning of the project and measured. If you don’t have an ongoing way of measuring the performance as the application progresses through the development lifecycle, you will find it difficult to pinpoint specific performance bottlenecks over time.

As an example, several years ago I met with core members of the Microsoft CLR team. They shared the fact that they compare performance on each night’s builds and if they find more than a couple microsecond deviations in the performance, the teams were required to identify the source of the performance degradation. When working with systems that have millions of lines of code, if the waited a week, it may become hard to impossible to identify the multiple places where performance has now dropped by 1/100th of a second. Over time these performance penalties build up.

I don’t mean to indicate that your Mom & Pop web site needs to live up to this stringent of a testing standard. Also, I’m not insinuating that you should prematurely over optimize your code, but try to make intelligent decisions and have ways of determining when your decisions negatively impact your performance up front.

Why do I bring this up in the context of LINQ to DB (SQL/EF)? If you’re not testing and monitoring your app, you may find that a nice abstraction layer that you added just killed your performance. In the case of the client’s application, they had nicely abstracted away the ability to load various database structures into a generic repository. They had separate methods to GetCustomerById, GetOrdersForCustomerId, GetOrderDetailsForOrderId, etc. They also had helper methods for validation including ValidateIsCustomerNameUnique. The downside here is that reading through the code, it wasn’t easy to notice where hidden database calls were being sprinkled through the code. This brings up rule number 2 for performance testing with databases:

RULE 2: Profile your application

Profiling your application for external requests, including services is essential to make sure the requests you are making are not causing a performance bottleneck. I highly recommend using some sort of profiling tool, particularly for people who are new to LINQ. LINQ makes it easy to make silly mistakes like n+1 requests to a database when navigating lazy-loaded parent-child relationships.

There are plenty of options for profiling applications. I identified some of them back in my LINQ Tools post. Some of these require adding code to your assemblies, while others simply attach to running processes.

If you have a license for SQL Server, you probably have access to SQL Profiler. To use this tool, create a new profile pointing it to your database and run your application. Once you have executed the code you want to profile, you can view all of the requests made against that database. Pay particular attention to cases where the same SQL is issued multiple times in succession or sequence. The downside here is that you will need to manually trace through your code base to find where each request is made in order to fix the issues.

Another alternative if you have the Ultimate SKU of Visual Studio is to use the Intellitrace feature added in Visual Studio 2010. Using Intellitrace, you can not only identify which SQL requests were issued to the database. You can also select each line in the results and navigate to the line of code that caused the request to be issued. Let’s consider this fairly innocuous code snippet to output the Order date and Product Names associated with each order:

   1:  Using model As New NwindEntities
   2:      For Each o In model.Orders.Take(3)
   3:          Console.WriteLine(o.OrderDate)
   4:          For Each od In o.Order_Details
   5:              Console.WriteLine(od.Product.ProductName)
   6:          Next
   7:      Next
   8:  End Using

Running this and putting a breakpoint on line 8, we can see the following Intellitrace output:

image

From here, we can see that as we iterate each order item, we are making a separate request to the database  for each associated order detail record to get the related product object. Clicking on any of the lines of the output will take you directly to the line of the code that the request was made. Unfortunately, you won’t be able to view the parameters for each request using Intellitrace as you could with SQL Profiler, but that’s less important from a performance tuning perspective than it is to know that you have multiple excessive requests to the database. If you find that the intellitrace output becomes cluttered with non-database related trace items, I often find it helpful to filter the results to only ADO.Net requests:

image

Fortunately, fixing the code above only requires changing line 2 in the code above to eagerly load the child records:

For Each o In model.Orders.Include("Order_Details").Include("Order_Details.Product").Take(3)

We may want to further optimize this request by not hydrating the entire objects, but rather just fetching the rows that we want as well:

Using model As New NwindEntities
    Dim query = From o In model.Orders
                Select o.OrderDate,
                    ProductNames = From od In o.Order_Details
                                   Select od.Product.ProductName

    For Each o In query.Take(3)
        Console.WriteLine(o.OrderDate)
        For Each p In o.ProductNames
           Console.WriteLine(p)
        Next
    Next
End Using

If you don’t have access to SQL Profiler or Intellitrace, consider one of the other relatively inexpensive profiling tools out there like the MVC MiniProfiler, ORM ProfilerHuagati’s LINQ to SQL Profiler, EF Prof, or at a bare minimum checking the generated code for your queries using LinqPad.

With your application now profiled, hopefully you won’t run into the issues such as found in the following code (which I did see in the customer’s app changing the model to again protect the guilty:

Debug.WriteLine(Customers.FirstOrDefault().CompanyName)
Debug.WriteLine(Customers.FirstOrDefault().ContactName)
Debug.WriteLine(Customers.FirstOrDefault().ContactTitle)
Debug.WriteLine(Customers.FirstOrDefault().Phone)
Debug.WriteLine(Customers.FirstOrDefault().Fax)
Dim CustomerOrders = Customers.FirstOrDefault().Orders
For Each order in CustomerOrders
    ' Load the order into a POCO
Next

Quick quiz boys and girls, without using a profiler how many requests are we making to our database here? Remember that not only will you have a database hit for each call to FirstOrDefault which doesn’t use deferred loading, but you’ll also get a call on GetEnumerator (called internally in the For Each iteration). Thus the count is 7 for the above code, right? Actually, it’s worse because hidden behind the Debug.WriteLine is a trace writer which also writes the value to the database’s log table. As a result we actually have 12 database requests (7 reads and 5 writes) instead of the single query that we should have used. In this case we’re breaking rule #3:

RULE 3: Don’t fetch needlessly

In the above code, we can simply fetch our target customer once and automatically include their associated Orders as follows:

Dim firstCustomer = Customers.Include("Orders").FirstOrDefault()
Debug.WriteLine(firstCustomer.CompanyName)
Debug.WriteLine(firstCustomer.ContactName)
Debug.WriteLine(firstCustomer.ContactTitle)
Debug.WriteLine(firstCustomer.Phone)
Debug.WriteLine(firstCustomer.Fax)
Dim CustomerOrders = firstCustomer.Orders
For Each order in CustomerOrders
    ' Load the order into a POCO
Next

In this case we fetch the firstCustomer once and reuse it rather than calling FirstOrDefault repeatedly. We also use the .Include option to eagerly fetch the child records. In this case, I’m saddened that the original developer didn’t use a bit of brain power to eliminate those extra database hits FOR LOGGING PURPOSES, but assume that it was because they weren’t aware of when their database was being hit. Of course, this brings us back to rule 2 – profiling.

Simply removing excessive database hits will almost always improve your code performance. In one case, I had a situation where a request was taking 10 minutes. After removing the excessive hits, the performance came down to 10 seconds, which was a definite improvement. However, 10 seconds still does not make the application web scale as the database’s CPU is pegged for that amount of time. Sometimes, it is actually best to break the process up a bit to improve performance.

RULE 4: Break up complex queries

To give you an idea of the kind of query that we’re talking about here, consider the following case where we are fetching the employees in USA including their regions and sales information.

Dim empOrders = 
    From e In Employees
    Where e.Country = "USA"
    Select 
        e.FirstName,
        e.LastName,
        Regions = From t In e.Territories
                  Select t.Region.RegionDescription
                  Distinct,
        TopThreeSales = From o In e.Orders
                        From od In o.OrderDetails
                        Select
                            od.Product.ProductName,
                            TotalSale = od.Quantity * od.UnitPrice
                        Order By TotalSale Descending

While this code will compile and run, the performance will start to suffer as larger volumes of data are added to the database. The reason is that both Territories and Orders are child collections from Employees. As a result, SQL will return the Cartesian product between the two sets. In other words, if a single employee is associated with 5 territories and has sold 10 products, the total number of rows returned would be 50. The OR/M is then responsible for splitting out those results again into the correct groupings. If you multiply this against 10,000 employees, you will find that there is a massive amount of excess data that is returned.

In this case, It may be helpful to split your sub queries up into separate database requests. You could do something like the following using the Contains clause to pass the Id’s of the parent record in to the subsequent  queries.

Dim empOnly = 
    (From e In Employees 
    Where e.Country = "USA" 
    Select 
        e.EmployeeID, 
        e.FirstName, 
        e.LastName). 
    ToList()

Dim EmpIds = empOnly.Select(Function(e) e.EmployeeID)

Dim TopThreeSales = 
    From o In Orders
    Where EmpIds.Contains(o.EmployeeID)
    From od In o.OrderDetails
    Select 
        o.EmployeeID,
        od.Product.ProductName,
        TotalSale = od.Quantity * od.UnitPrice
    Order By TotalSale Descending

However “Contains” has a couple of hidden surprises that limit our use here. First if you use Contains, you can not make it into a compiled query because the number of parameters vary at run-time. Second, if you have more than 2100 items in your EmpIds collection, you will run into a hard limit in SQL Server which only allows up to 2100 parameters. In this event, it is better to re-apply the original filter and return the new result sets for each of the subsequent queries. In the end we can join the separate queries back together again using LINQ to Objects:

Dim empOnly = 
    (From e In Employees
    Where e.Country = "USA"
    Select 
        e.EmployeeID,
        e.FirstName,
        e.LastName).
    ToList()

Dim Regions = 
    (From e In Employees 
    Where e.Country = "USA"
    From t In e.Territories
    Select 
        e.EmployeeID,
        t.Region.RegionDescription
    Distinct).
    ToList()

Dim TopThreeSales = 
    (From e In Employees 
    Where e.Country = "USA"
    From o In e.Orders
    From od In o.OrderDetails
    Select 
        o.EmployeeID,
        od.Product.ProductName,
        TotalSale = od.Quantity * od.UnitPrice
    Order By TotalSale Descending).
    ToList()
                
Dim combined = 
    From e In empOnly
    Select 
        e.FirstName,
        e.LastName,
        EmpRegions = Regions.Where(Function(reg) e.EmployeeID = reg.EmployeeID),
        Sales =  TopThreeSales.Where(Function(sale) e.EmployeeID = sale.EmployeeID)
    

In the above referenced project, I was able to take some queries that as a single LINQ statement took 10 seconds to run on the database down to sub-second requests. Your mileage may vary using this technique. If at all unsure, refer back to Rule 2: Profile.

RULE 5: Use ORM by default but Stored Proc where necessary

At times you will find that the generated query is too complex and the database has issues trying to parse the generated SQL. The complexity of your query, particularly the number of joins and depth of the object graph/inheritance model you are traversing can cause issues. In these cases, I have no objections to using Stored Procedures in order to wrangle the otherwise unruly queries. LINQ to DB is great for the 70-80% of crud operations, but there are times, particularly when reporting when you need something else. Thankfully LINQ to SQL and LINQ to EF both support consuming stored procedures when the need arises without the need to write the tedious and potentially error prone custom ADO code yourself.

In addition, LINQ is not a replacement for ETL operations. In one case, we had a situation where saving a single record with 2000 children caused the database to churn for 10 minutes due to 2001 individual hits to the database for the update process (on a single SaveChanges call). We re-wrote that operation using BulkCopy and brought the operation down to 1 second from 10 minutes.

RULE 6: Use Appropriate Sample Data

The last item for today is to make sure when developing to have representative quantities of data in your sample as you will have after a couple of years of production data enters your system. We found a number of cases where complex queries like I described in rule 4 above would perform fine in development where we had thousands of rows of data, but when we applied it against the production data which had millions of rows of data, the performance died. The complex joins which worked fine against smaller data sets no longer worked against the bigger sets. If we had a good approximation of data volumes in development, we would have been able to diagnose and fix this issue before shipping the version to production.

That’s just a couple of my rules of thumb which have helped me diagnose and fix performance issues with LINQ to SQL/EF. If you have any tricks or techniques to add, please let me know what you Thinq.

Posted on - Comment
Categories: LINQ - VB Dev Center - Entity Framework -

LINQ to Entity Visualizer

When demonstrating the LINQ tools, I typically start out showing the LINQ to SQL visualizer that’s available with the C# Samples. Today I saw that Raja Venkatesh has released a Visualizer for ObjectQuery<T> (aka. LINQ to Entities). As you do with the other visualizers, you enable this by simply saving the AnySourceEntityQueryVisualizer.dll to your Visualizers directory. )Note: :the download page specifies to copy it to your C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers. However, Windows 7 blocks saving files there by default. Alternatively, you can copy it to your My Documents\Visual Studio 2008\Visualizers.

Once you install it, put a breakpoint after your query is declared. If you hover over the query variable, you should see the magnifying glass indicating the debugger visualizer:

image

Clicking on the magnifying glass brings you to a screen that shows the Expression, projected SQL, and Connection properties. If you click “Execute”, you will see the server log and a grid with the results.

image

If you want to try it out, feel free to download it from the Visual Studio Gallery page for the LINQ to Entity Visualizer. I’ll be adding a linq to this on my LINQ Tool list as well.

Posted on - Comment
Categories: Entity Framework - VS 2008 - VS 2010 -

LINQ to SQL enhancements for 2010

One question that I'm asked repeatedly is, "Is LINQ dead?" The quick answer is, NO. The more appropriate question is "Is LINQ to SQL dead?" That one is a bit trickier, particularly after some of the blog posts from the data programmability team regarding their emphasis moving forward for LINQ to SQL and the Entity Framework.

My take on it is that LINQ to SQL is in a similar situation to Winforms. Both are still supported and have teams dedicated to them, but don't expect much in terms of new features, rather the focus is on bug fixes. The main development focus for new features is placed more on the Entity Framework and similarly WPF. For those who love taking SAT tests, you can think of it as

LINQ to SQL : Entity Framework :: Winforms : WPF

Proof of the point, Damien Guard, one of the people on the LINQ to SQL team, just posted a list of 40+ changes that are coming for LINQ to SQL for .Net 4.0. Looking through the list, most of the items are bug fix items and not feature enhancements. 

Of the list of items, the biggest change I see is specifying the text parameter lengths. Adding this eliminates some of DBA's performance concerns in terms of query plan reuse. This is one area that DBA's have focused on in terms of the performance issue and was an unfortunate oversight in the initial release.

There are a number of larger features that people continue to ask for that are not being included.

  • Support for more complex table to object relationships. This is really the point of the EDM, so I don't see this ever making it into LINQ to SQL.
  • Ability to update a model from database schema changes. Again, the EDMX designer supports this, so I wouldn't hold your breath.
  • No support for SQL 2008's new data types, including the Spatial types, HierarchyId and Filestream. If any of the features were added, I would expect this to be included at some point.

Damien's list should be proof that LINQ to SQL is not dead, but it isn't going to receive significant enhancements that you may want. Check out the 2010 beta and see what changes are there for yourself and give feedback to the teams before it's too late.

Posted on - Comment
Categories: Entity Framework - LINQ - VS 2010 -

ADO.NET Entity Framework Documentation Samples in VB

Last week, I announced that my translations of the Entity Framework samples were available in VB. Today the ADO.Net team announced that next set have been posted. These are part of the ADO.Net Entity Framework Documentation Samples. These are the projects that are used in the EF quick start and walkthroughs that come with the .Net documentation. They are a set of mini applications demonstrating using EF within the context of an application.

The Course Manager sample was previously translated, but the HR Skills, Adventureworks data binding and research and collaboration tool were just updated today. Unlike the other samples, these don't have separate downloads for each sample, but rather have both C# and VB versions included with each download. Here's the description of each of these projects as taken from the MSDN site:

  • CourseManager.zip
    The CourseManager Windows forms application created by completing the Entity Framework quickstart.
  • HRSkillsCombined.zip
    This is a Visual Studio 2008 solution that contains both a Windows forms project and an ASP.NET project. Both samples demonstrate data binding to entity objects. The ASP.NET sample uses the EntityDataSource control for data binding.
  • AdWksSalesWinDataBind.zip
    The AdventureWorks Data Binding sample demonstrates data binding that uses the Entity Framework. This application displays and modifies SalesOrderDetail entities associated with SalesOrderHeader entities.
  • ResearchCollaborationAssistant.zip
    The Annotation and Research Collaboration Tool aids research and collaboration by creating reference annotations and contact entities that can be searched for both relevant Web pages and people associated with topics or search texts.

I hope you find these samples helpful. I'm not sure that I would recommend using the manual databinding that the team used when creating these samples as there are quite a few cases where they could have relied on native databinding rather than manually adding items to text boxes. These translations were fairly literal translations on purpose.

If you're just wanting to learn the query syntax and see the capabilities of EF, the Entity Framework Query Samples are a better source of information.

Thanks to both the VB Team and Data Team for recognizing the need for these samples in VB.

Posted on - Comment
Categories: Entity Framework - VB Dev Center - VB - ADO.Net Data Services -

Entity Framework Samples in Visual Basic

For those Visual Basic users out that that have struggled with the fact that the samples were only available in C#, you can now rejoice. There are a number of projects that have now been translated into Visual Basic for your learning pleasure. You can find these samples on the MSDN Code Gallery’s Entity Framework page. At this point the following projects have been translated.

  • Entity Framework Query Samples Compatible with .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 (Visual Basic and C# versions available)
    The Entity Framework Query Samples is a small Windows Forms program that contains several basic Entity SQL and LINQ to Entities queries against that NorthwindEF Entity Data Model (based on a modified version of Northwind). Its goal is to help you learn the features of the two query languages supported by EF and visualize how the results and the translated store query look like.
  • Entity Framework Lazy Loading Compatible with .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 (Visual Basic and C# versions available)
    This sample shows how to use code generation to add support for transparent lazy loading to Entity Framework. It includes code generator (EFLazyClassGen), supporting library (Microsoft.Data.EFLazyLoading) and sample test applications.
  • Persistence Ignorance (POCO) Adapter for Entity Framework V1 Compatible with .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 (Visual Basic and C# versions available)
    EF POCO Adapter enables Plain Old CLR Objects (POCOs) to be tracked using released version of Entity Framework V1 using automatically generated adapter objects. It consist of a code generator, supporting library and a test suite and examples.

There are several more on the way. I’ll try to update this post when they become available.

5/22: Update: Two more samples went online today:

  • EF Extensions Compatible with .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 (Visual Basic and C# versions available)
    The ADO.NET Entity Framework Extensions library includes utilities that make querying stored procedures, creating typed results from DB data readers and state tracking external data much easier in the Entity Framework. A sample application demonstrates several patterns using these utilities, including stored procedures with multiple result sets, materialization of CLR types, and registering entities in the Entity Framework state manager.
  • ADO.NET Data Services IUpdateable implementation for Linq to Sql
    Sample implementation of ADO.NET Data Services IUpdateable interface for Linq to Sql Data Sources.
Posted on - Comment
Categories: Entity Framework - VB - VB Dev Center - LINQ - ADO.Net Data Services -

Julie Lermans Programming the Entity Framework

I had the pleasure of reviewing an early release of Julie Lerman's Programming the Entity Framework. Julie just reported that it has just been sent to print. Having published LINQ in Action last year, I know what a relieve it can be to get a project of this size out the door.

It is a good read full of information that is only possible to gain by using it in real life applications. She's done a good job not only of presenting the framework, but also giving recommendations on how to use it in a variety of application environments. Special attention is given to the trials and tribulations of building n-tier applications with the Entity Framework.

If you are interested in taking your LINQ knowledge and moving up to the Entity Framework, I recommend checking it out. Head on over to her blog to find out how to pre-order your copy.

Posted on - Comment
Categories: Entity Framework -

Changing the Namespace on generated Entity Framework classes

As I was preparing a presentation recently, I started hitting my head into a brick wall when trying to change the namespace on the entities generated by the Entity Framework. Having spent so much time with LINQ to SQL, I was anticipating that the behavior would be similar enough to make this easy. Unfortunately, I was mistaken.

First, what I tried to do wrong. With LINQ to SQL, if you click the unused design surface, you can set the namespace for the Context separately from the Entities through the property window of the dbml file.

The Entity designer window with the edmx file also has a namespace option in the property window. In this window you can set the Namespace for the ConceptualEntityModel's Schema. Notice from the image here, that the help indicates that this should be "The namespace for the Entity Data Model." Unfortunately, this does not mean that it will be the namespace used by the classes that the code generation tool uses when it generates the actual VB or C# classes that represent the conceptual model.

After jumping back and forth between the XML and classes and the Class View, trying to build and rebuild the project, I got very frustrated because the namespace that I specified appeared in the EDMX file, but the generated classes were not appearing with the correct namespace. I finally gave up and sought out a bit of help. Shawn Wildermuth came to the rescue and pointed me to the property window of the NWindModel.Edmx file itself rather than the the property window of an area in the design surface.

On the property window for the .Edmx file we need to set the value for the Custom Tool Namespace. Once that is done, our classes will be generated in the namespaces that we expected.

Looking a bit deeper at this provides some interesting information. The LINQ to SQL dbml file saves the EntityNamespace and ContextNamespace in the Database element:

<Database Name="Northwind" EntityNamespace="Linq" ContextNamespace="Linq" Class="NWind2DataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">

In contrast, the namespace that we set on the custom tool namespace is not included within the EDMX at all. Instead, it is contained in the actual project file (vbproj or csproj):

<ItemGroup>
   <
EntityDeploy Include="NWindModel.edmx">
      <
Generator>EntityModelCodeGenerator</Generator>
      <
LastGenOutput>NWindModel.Designer.cs</LastGenOutput>
      <
CustomToolNamespace>NWindBo.NWindModel</CustomToolNamespace>
   </
EntityDeploy>
</
ItemGroup>

Posted on - Comment
Categories: Entity Framework - LINQ -

Win7 and the LINQ to SQL and LINQ to Entity designers

I've been playing with the Windows 7 Beta1 since they came out. So far, I've been really impressed with what I'm seeing. I've installed quite a bit and have put a full development environment on it including Visual Studio 2008 and SQL Server 2008.

So far, the only real thing I've seen is a small bug in the LINQ to SQL and LINQ to Entity Framework design surfaces. In these, if you move the mouse over one of the entities on the designer, the entity may dissappear.

There's a quick work-around for this issue. Simply move the vertical scroll bar down. Once you do that, the entities will remain visible on the design surface. Rest asured, the development team is aware of this glitch and I'm sure there will be a fix for it by the time that the bits ship.

Posted on - Comment
Categories: Entity Framework - LINQ - VS 2008 -

ADO.Next and the Entity Framework

Last month, a document describing ADO.Next was published and quickly pulled. A new version was just posted to http://msdn.microsoft.com/data/. I read the original document, but neglected to save a copy of it before it was pulled. Skimming over the new ADO.Next document and the ADO Entity Framework documents, that were posted on 6/15, I see that there appear to have been a number of significant changes made in the last month. I hope to read through them more thoroughly in the near future and comment on them at that point. At least this time, I remembered to save and print the documents.

From the looks of things, the new documents look much more promising and allude to some new tool sets to make mapping relational data structures to object heirarchies much easier. One tool appears to be similar to the BizTalk mapper (including the functoids) to create XML based mapping between the tables and objects. They also appear to be extending the DLINQ designer to allow for virtual views, or objects which are based on multiple data structures. Both of these are good things in my opinion and may help us move more easily from the table centric mindsets typical of people who see the simple demos and think that they are indicative of the kinds of applications we should build in real-life.

Posted on - Comment
Categories: Entity Framework -