Welcome to MSDN Blogs Sign in | Join | Help

There has been a variety of responses to the post on L2S futures in the last couple of days.

Let me start by saying sorry for the radio silence since the post but, as Elisa mentioned,  we posted it while at PDC and were focusing on the interactions there over the last couple of days.

There are a couple specific points that I would like to clarify:

Is LINQ dead?

No… heck no…

There is a big difference between LINQ to SQL and LINQ.

LINQ is Language Integrated Query, today we ship the following sources over which one can execute a LINQ query:

  • DataSet : LINQ to DataSet
  • XML: LINQ to XML
  • In Memory Objects: LINQ to Objects
  • ADO.NET Data Services (Astoria) Client: LINQ to Data Services
  • LINQ to Relational Databases:
    • LINQ to SQL – the technology we were discussing in the original post
    • Entity Framework (LINQ to Entities)

There are many other people in the company and broader community working on LINQ solutions to other data sources. We are also excited to see LINQ being applied to many cool new problems beyond the typical data access scenario.

The discussion in the post was about the difference in investment level that we will have going forward regarding LINQ to SQL and the Entity Framework. LINQ itself, is a fundamental technology that we will continue to bet heavily on.

So what exactly is the announcement about?

Over the last few months we have been looking at how to carry forward LINQ to SQL and LINQ to Entities. At first glance one may assert that they are differentiated technologies and can be evolved separately. The problem is that the intersection of capabilities is already quite large and the asks from users of each technology takes the products on a rapid feature convergence path. For example, common asks for LINQ to Entities (that are being delivered with .NET 4.0) are POCO and Lazy Load.  Similarly, in the LINQ to SQL side we are being asked to provide new mapping strategies and other features which the EF already has. Additionally there are common asks for new features like UDT’s and better N-Tier support for both stacks. The announcement really centers around the point that,  after looking hard  at this and triangulating with internal partners and customers, we decided to take the EF forward with regards to the overall convergence effort and over time provide a single solution that can address the various asks.

Is LINQ to SQL Dead?

We will continue make some investments in LINQ to SQL based on customer feedback. This post was about making our intentions for future innovation clear and to call out the fact that as of .NET 4.0, LINQ to Entities will be the recommended data access solution for LINQ to relational scenarios. As mentioned, we have been working on this decision for the last few months. When we made the decision, we felt that it was important to immediately to let the community know. We knew that being open about this would result in a lot of feedback from the community, but it was important to be transparent about what we are doing as early as possible.  We want to get this information out to developers so that you know where we’re headed and can factor that in when you’re deciding how to build future applications on .NET.  We also want to get your feedback on the key experiences in LINQ to SQL that we need to add in to LINQ to Entities in order to enable the same simple scenarios that brought you to use LINQ to SQL in the first place.

Tim Mallalieu
Program Manager, LINQ to SQL and LINQ to Entities

Since the release of LINQ to SQL and the Entity Framework, many questions have been raised about the future plans for the technologies and how they will relate to each other long term.
During this week of PDC we are now at a point, with the announcement of Visual Studio 10 and the .NET Framework 4.0, that we can provide more clarity on our direction.
 
We have seen great momentum with LINQ in the last year.  In .NET Framework 3.5 we released several LINQ providers, including LINQ to SQL which set the bar for a great programming model with LINQ over relational databases.  In .NET 3.5 SP1, we followed up that investment with the Entity Framework enabling developers to build more advanced scenarios and to use LINQ against any database including SQL Server, Oracle, DB2, MySQL, etc.
 
We’re making significant investments in the Entity Framework such that as of .NET 4.0 the Entity Framework will be our recommended data access solution for LINQ to relational scenarios.  We are listening to customers regarding LINQ to SQL and will continue to evolve the product based on feedback we receive from the community as well.

Tim Mallalieu
Program Manager, LINQ to SQL and Entity Framework

Another Entity Framework-enabled ADO.NET providers post!  Woohoo!

 

It is my pleasure to announce that as part of the release of SQL Anywhere 11, Sybase iAnywhere has added Entity Framework support to their ADO.NET provider.  For more information on the SQL Anywhere 11 release, please see the following announcement on the Sybase web site:

    http://www.sybase.com/detail?id=1057559 

 

Congratulations to everyone else at Sybase who contributed to the release!

 

Enjoy!

 

David Sceppa

ADO.NET Program Manager

Last week, we covered Eager Loading and how to migrate LINQ to SQL based code that took advantage of Eager Loading. This week, we discuss Deferred Loading.

Generally speaking, queries only retrieve the objects you request, and not their related objects. Deferred Loading (or Lazy Loading) allows you to automatically load objects on demand if and when you attempt to access the object that is not yet loaded (you might do this by trying to access a property that allows you to get to the object you are interested in, for instance).

Automatic Deferred Loading has its advantages and disadvantages – automatic deferred loading that is on by default means more productivity and less code to write. However, it also means less control over when and how you hit the database. In LINQ to SQL, Automatic Deferred Loading is enabled by default, but it can be disabled by using the following code fragment. For more information, see Deferred versus Immediate Loading (LINQ to SQL).

db.DeferredLoadingEnabled = false;

In the example below, you are really only querying for  objects from the Products table – however, because Deferred Loading is enabled, you can access prod.SalesOrderDetail (which automatically fetches the associated SalesOrderDetail values from the database, and surfaces the results as SalesOrderDetail objects for the particular product)

var products = from prod in db.Products
               where prod.Color == "Blue"
               select prod;

foreach (Product prod in products)
{
    foreach (SalesOrderDetail detail in prod.SalesOrderDetail)
    {
        // do something with detail
    }
}

The Entity Framework does not provide an automatic mechanism for deferred loading.  However, a simple addition to the code above achieves the same result.

var products = from prod in db.Product
               where prod.Color == "Blue"
               select prod;

foreach (Product prod in products)
{
    // avoids unnecessary queries
    if (!prod.SalesOrderDetail.IsLoaded)
    {
        prod.SalesOrderDetail.Load();
    }

    foreach (SalesOrderDetail detail in prod.SalesOrderDetail)
    {
        // do something with detail
    }
}

For more information, see Navigation Properties. Also see Jaroslaw Kowalski’s blog series Transparent Lazy Loading for Entity Framework which discusses the EFLazyClassGen samples available on CodeGallery.  EFLazyClassGen could also be extended to support a Link<T> style deferred loading of individual properties.

In our next post, we will look at Stored Procedures. Stay tuned and let us know what you think!

- The ADO.NET Team

 

I always enjoy making announcements regarding external providers releasing their Entity Framework-enabled ADO.NET providers.

 

It is my pleasure to announce that Npgsql has released a version 2.0 of their ADO.NET provider for PostgreSQL, which includes support for the Entity Framework.  For more information, see the following announcement on the PgFoundry web site:

    http://pgfoundry.org/frs/shownotes.php?release_id=1230

 

Congratulations to Josh Cooley and everyone else on the Npgsql team who contributed to the release!

 

Enjoy!

 

David Sceppa

ADO.NET Program Manager

Since the release of the Entity Framework, we have received a number of requests for details and best practices from customers who are looking at migrating their LINQ to SQL based applications to the Entity Framework.  In order to address this topic, we are beginning a new series of blogs posts that will look at various aspects of migration.

This first post in the series covers Eager Loading in LINQ to SQL, and the steps for migrating to equivalent constructs in the Entity Framework in .NET 3.5 SP1. Subsequent posts will cover Deferred Loading, LINQ specifics, concurrency, mapping, stored procedure support, and other topics. As we continue to approach the next release of the Entity Framework we will revisit how some of the new features aid in migration.

What is Eager Loading?

Eager, or immediate, loading occurs when you query for an object and all of the related objects are also returned. One of the major differences in how LINQ to SQL and the Entity Framework implement eager loading is that LINQ to SQL allows eager loading behavior to be specified at the context level, and the Entity Framework supports it at the query level.

Eager Loading an entity’s related data with LINQ to SQL

LINQ to SQL allows you to define the eager loading behavior at the Context level. The DataLoadOptions class allows you to define the load behavior and attach it to a context. This defines the eager loading behavior for all entities that are fetched for that particular DataContext instance. For more information, see Deferred versus Immediate Loading (LINQ to SQL).

DataLoadOptions dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Customer>(c => c.Order);
db.LoadOptions = dataLoadOptions;

List<Customer> customers = db.Customer.ToList();

Eager Loading an entity’s related data with Entity Framework

The Entity Framework allows you to define eager loading at the query level by using the Include method. For more information, see Shaping Query Results.

List<Customer> customers = db.Customer.Include("Order").ToList();

The scope of eager loading differs between LINQ to SQL and the Entity Framework. LINQ to SQL supports per-context eager loading options and the Entity Framework supports per-query eager loading options.

Using LINQ to SQL for cascading eager loading spanning multiple entity types

In LINQ to SQL, you can define eager loading for any type of entity that is passed with the LoadWith method. For example, you can specify EntitySets that are directly available on an entity as an argument. For each EntitySet that is to be eager loaded, declare a new LoadWith clause and include it as a part of DataLoadOptions.

If this is done for a chain of hierarchy as shown in the below example, Customer ->Loadwith ->Orders->Loadwith ->OrderDetails, we can eagerly load multiple levels in the object graph.

DataLoadOptions dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Customer>(c => c.Order);
dataLoadOptions.LoadWith<Order>(c => c.OrderDetail);
db.LoadOptions = dataLoadOptions;

List<Customer> customers = db.Customer.ToList();

Cascading Eager Loading in Entity Framework

The Include method allows multiple hierarchies of the EntityCollection to be denoted with dot (.) notation.

 

List<Customer> customers = 
db.Customer.Include("Order.OrderDetail").ToList();

In the Entity Framework, a single call of the Include method can eagerly load the multilevel hierarchy in an EntityCollection, per query.

Eager Loading of multiple relationships in LINQ to SQL

In LINQ to SQL, multiple EntitySets can be eagerly loaded with an entity by adding each one of them using the LoadWith method of the DataLoadOptions class and attaching the DataLoadOptions object to the DataContext.

DataLoadOptions dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Product>(c => c.OrderDetail);
dataLoadOptions.LoadWith<Product>(c => c.Supplier);
db.LoadOptions = dataLoadOptions;

Product firstProduct = db.Product.First();

Eager Loading of multiple relationships in Entity Framework

In the Entity Framework, you can use the Include method multiple times in a query to eager load multiple EntityCollections.

Product firstProduct = 
db.Product.Include("OrderDetail").Include("Supplier").First();

LINQ to SQL keeps multiple LoadWith clauses in an array within DataLoadOptions. The Entity Framework allows you to add multiple Include methods on an entity for a particular query.

In our next post, will look at Deferred/Lazy Loading. Stay tuned and let us know what you think!

- The ADO.NET Team

 

Microsoft's premier developer event, the Professional Developer Conference, is almost here. PDC 2008 will feature more than 160 sessions covering a wide range of topics including a number of great sessions from the ADO.NET Team, such as:

Developing Applications Using Data Services

Presenter: Mike Flasko

In the near future, applications will be developed using a combination of custom application code and online building block services, including data-centric services. In this session we discuss advancements in the Microsoft development platform and online service interfaces to enable seamless interaction with data services both on-premises (e.g., ADO.NET Data Services Framework over on-premises SQL Server) and in the cloud (e.g., SQL Server Data Services). Learn how you can leverage existing know-how related to LINQ (Language Integrated Query), data access APIs, data-binding, and more when building applications using online data.

Offline-Enabled Data Services and Desktop Applications

Presenter: Pablo Castro

The ADO.NET Data Services Framework (a.k.a. Project "Astoria") introduced a way of creating and consuming flexible, data-centric REST services. By combining data services with the Microsoft Sync Framework, learn how to create offline-capable applications that have a local replica of their data, how to synchronize that replica with an online data service when a network connection becomes available, and how replicas can be used with the ADO.NET Entity Framework. Also, hear us talk about our plans, see the tools that help client- and server-side setup, and discuss the runtime components and APIs.

clip_image002

Entity Framework Futures

Presenter: Tim Mallalieu

The next version of the Entity Framework adds scenarios in the areas of   model driven development, domain driven development, simplicity, and integration. See a preview of production and prototype code for the next version of the Entity Framework as well as a candid discussion with members of the development team.

See you there!!

Elisa Flasko
Program Manager, Data Programmability

I spoke too soon, or actually a little too late.  Robert Simpson at Phoenix Software Solutions politely reminded me that their SQLite ADO.NET provider also supports the ADO.NET Entity Framework.  For more information, see the Phoenix Software site at:

    http://sqlite.phxsoftware.com/

 

In fact, the initial build of the SQLite provider that supported the RTM version of the Entity Framework was available the same day that the Entity Framework released.

 

Congratulations to Robert, to Phoenix Software Solutions and to SQLite!

 

Enjoy!

 

David Sceppa

ADO.NET Program Manager

It is my pleasure to announce the first (to the best of my knowledge) external providers to support the ADO.NET Entity Framework!


Devart (formerly Core Lab) has released a new version of their ADO.NET providers, which includes support for the Entity Framework.  For more information, see the following announcement on Devart's web site.  Congratulations to the folks at Devart!

    http://devart.com/news/2008/directs475.html

 

With the release of Devart's providers, developers can now acess their Oracle, MySQL and PostgreSQL databases via the Entity Framework.  I've downloaded and used their OraDirect.NET provider to successfully run sample queries against an Oracle database using both LINQ and Entity SQL.

 

Enjoy!

 

David Sceppa

ADO.NET Program Manager

Hey everyone!

I am Himanshu. I am a program manager in the ADO.Net team. Today I am going to talk about Table-Valued parameters that are new in SQL Server 2008. About 4 years back I was writing an application which involved adding metadata about my music library into a database. The database had a table each for storing Artists, Albums, and Songs. While adding an Album of songs into the database I had to insert data into each of these tables. I had defined stored procedure for inserting data into each of the tables. In the first iteration there was a bug in the code due to which these operations were not being done in a single transaction. Needless to say this bug surfaced as a data-corruption issue later on. Once identified the fix was trivial, ensure that all commands are executed in a single transaction. However, what I would have really liked to do was to be able to call a single stored procedure to which I could pass the metadata about the Album and the list of songs at the same time. But there was no good way of accomplishing this back then. I was programming against SQL Server 2000 back then. I am excited to say that now with the new table-valued parameters in SQL Server 2008 I can finally write a single stored procedure that will let me accomplish this without any kind of hacks!

Table-Valued parameters, as the name suggests lets you pass a table as parameter to a stored procedure. In order to use table-valued parameters you need to define a table type and then use the table type in the definition of the stored procedure. Let me illustrate this with the help of an example. I am going to first create a table type named Songs_TableType with two columns, Title and TrackNumber. Then I will use it in a stored procedure to pass a table as parameter.

First creating the table type

Create Type Songs_TableType as Table
(Title nvarchar(120) not null,
TrackNumber int)

I can now use this type in a stored procedure to pass a table as a parameter. The following T-Sql shows how to define a stored procedure that takes this type as a parameter. Note that I have skipped error handling for brevity.

create procedure AddSongs(
 @ArtistName nvarchar(120), 
 @AlbumName nvarchar(120), 
 @Songs Songs_TableType READONLY)
as
begin
 -- Add the Artist
 Declare @ArtistID int
 insert into Artists values (@ArtistName)
 select @ArtistID = SCOPE_IDENTITY()

 -- Add the Album
 Declare @AlbumID int
 insert into Albums values (@AlbumName, @ArtistID)
 select @AlbumID = SCOPE_IDENTITY()

 -- Insert songs
 insert into Songs 
 select title, trackNumber, @AlbumID, @ArtistID
 from @Songs
end 

In the next post I will go into more details into how I can use the stored procedure defined above to simplify the code I have on the client. Till then, adios!

Himanshu Vasishth
Program Manager
ADO.NET

There were a number of changes to the Entity Framework and the designer between Visual Studio 2008 SP1/ .NET Framework 3.5 Beta and RTM that will require updates to existing source code. These breaking changes are listed below, including the mitigation for adjusting to the new behavior, and a side by side comparison of Beta code and RTM code.

Jeff Derstadt
Entity Framework Developer

Provider Changes

1. The Function property of DbFunctionCommandTree is renamed to EdmFunction.
Affects:
       - Provider writers

Mitigation:
       - Replace ".Function" wtih ".EdmFunction"

SP1 Beta Code:

funcTree.Function

SP1 RTM Code:

funcTree.EdmFunction

2. DbExpression, DbAggregate and DbModificationClause no longer have 'CommandTree' property

Affects:
       - Provider writers

SP1 Beta Code: 
Provider writers were able to go directly from an expression to a command tree, so when visiting          a command tree in CreateDbCommandDefinition, the expression instance was enough to have.

public DbCommandDefinition CreateDbCommandDefinition(
DbProviderManifest manifest, 
DbCommandTree commandTree)
{
    commandTree.Validate();
    DbQueryCommandTree queryTree = (DbQueryCommandTree)commandTree;
    string tsql = this.Visit(queryTree.Query);
    return new CustomCommandDefinition(queryTree.Parameters, tsql);
}
 
...
 
public override string VisitParameterReferenceExpression(
DbParameterReferenceExpression expression)
{
    if (!expression.CommandTree.Parameters.ToDictionary(p => p.Key, p => p.Value).ContainsKey(expression.ParameterName))
    {
       throw new ArgumentException("Invalid parameter name");
    }
 
    return "@" + expression.ParameterName;
}

SP1 RTM Code: 
Providers must now keep a reference to the command tree that was passed as an argument to CreateDbCommandDefinition if they need to refer back to it.

private DbCommandTree _currentTree;

public DbCommandDefinition CreateDbCommandDefinition(
DbProviderManifest manifest, 
DbCommandTree commandTree)
{
// no need to call commandTree.Validate()  
 // EF has already done so and the tree cannot change
DbQueryCommandTree queryTree = (DbQueryCommandTree)commandTree;
this._currentTree = commandTree;
string tsql = this.Visit(queryTree.Query);
return new CustomCommandDefinition(queryTree.Parameters, tsql);
}

...

public override string VisitParameterReferenceExpression(
DbParameterReferenceExpression expression)
{
if (!this._currentTree.Parameters.ToDictionary(p => p.Key, p => p.Value).ContainsKey(expression.ParameterName))
{
throw new ArgumentException("Invalid parameter name");
}

return "@" + expression.ParameterName;
}

3. DbCommandTree.Validate method is removed

Affects:
       -
Provider writers

4. DbCommandTree and DbExpression no longer have a Clone method

Affects:
       -
Provider writers

SP1 Beta Code: 
Provider writers were previously able to clone a command tree or a expression, e.g:

DbCommandTree tree = ...
DbCommandTree clonedTree = tree.Clone();

DbQueryCommandTree queryTree = ...
DbExpression clonedExpression = queryTree.Query.Clone();
 

SP1 RTM Code: 
Providers will no longer be able to clone a DbCommandTree or a DbExpression

5. DbNaryExpression is removed from the CommandTree API

Affects:
       - Provider Writers

Workaround:
       - Use DbArithmeticExpression

SP1 Beta Code:

IList<DbExpression> arg = ((DbNaryExpression)exp).Arguments;

SP1 RTM Code:

IList<DbExpression> arg = ((DbArithmeticExpression)exp).Arguments;

6. ProviderManifest.Provider and ProviderManifest.Token properties have been removed

Affects:
       - Provider Writers

SP1 Beta Code:

protected override DbCommandDefinition CreateDbCommandDefinition(
DbProviderManifest providerManifest,
DbCommandTree commandTree)
{     
  if(!SqlProviderManifest.ProviderInvariantName.Equals(
     providerManifest.Provider, StringComparison.Ordinal))
  {
   throw EntityUtil.Argument(...);
  }
 
  ...
 
}

SP1 RTM Code:

protected override DbCommandDefinition CreateDbCommandDefinition(
DbProviderManifest providerManifest,
DbCommandTree commandTree)
{     
  if(!(providerManifest is SqlProviderManifest))
  {
   throw EntityUtil.Argument(...);
  }
 
  ...
 
}

7. DbFunctionExpression IsLambda and LambdaBody properties are now internal

Affects:
       - Provider Writers

SP1 Beta Code: 
In provider code it was possible to inspect the values of the IsLambda and Lambda body parameters, but they would always be false and null, respectively.

protected override void VisitDbFunctionExpression(
DbFunctionExpression expression)
{ 
if(expression.IsLambda) {
throw EntityUtil.NotSupported(...);
}

GenerateFunctionInvocationSql(expression);
}

SP1 RTM Code:
Any code that was testing the values of these properties is unnecessary.

protected override void VisitDbFunctionExpression(
DbFunctionExpression expression)
{ 
GenerateFunctionInvocationSql(expression);
}

Entity Services Changes

1. The Metadata keyword in an entity connection string is now required.

Affects:
       - EntityConnection and ObjectContext users

SP1 Beta Behavior: 
In SP1 Beta, initializing an EntityConnection with a connection string that that doesn't have a Metadata keyword would not throw on the ConnectionString setter or constructor, but would throw on calls to Open() and GetMetadataWorkspace().

SP1 RTM Behavior: 
In SP1 RTM, the EntityConnection will throw in the ConnectionString setter or constructor.

2. EntityDataReader no longer overrides Object.GetHashCode() and Object.Equals(Object object)

Affects:
       - EntityDataReader users

SP1 Beta Code:
Object.Equals(Object object)

Users could have compared two data readers for equality.

Object obj = …
EntityDataReader reader = …

reader.Equals(obj);

Object.GetHashCode()

Users could have used instances of EntityDataReader as keys in data structures relying on hashing algorithms such as a hash table or a dictionary.

System.Collections.Hashtable hashtable = new Hashtable();
EntityDataReader reader1 = …
hashtable.Add(reader1, "first");

SP1 RTM Code:
Object.Equals(Object object)

Unchanged, but the result would be based on the default implementation.

Object.GetHashCode()

The default implementation of GetHashCode does not guarantee unique return values for different objects. Thus while the same code would run, it would be officially not supported.

Mapping and Metadata Changes

1. Compile time view generation hash has changed

Affects:
       - Users of compile time view generation

Mitigation:
       -
Anyone who uses compile time view generation will need to regenerate the views and recompile
         them.

2. SSDL no longer allows periods in Entity, Association, EntityContiner, EntitySet, AssociationSet, and Function names

Affects:
       - Metadata artifact authors

Mitigation:
        -
Names need to be changed so that they do not include periods

SP1 Beta Code:

<EntityType Name="Entity.1">
...
</EntityType>
<EntityContainer Name="Entity.Container">
 <EntitySet Name="Entity.1"
             Entity="My.Namespace.[Entity.1]"/>
</EntityContainer>

SP1 RTM Code:

<EntityType Name="Entity_1">...</EntityType><EntityContainer Name="Entity_Container"> <EntitySet Name="Entity_1" Table="Entity.1"
             Entity="My.Namespace.Entity_1"/></EntityContainer>

3. MetadataException constructors no longer take DataSpace string

Continue to use the following constructors to construct MetadataException.

public MetadataException(string message)
public MetadataException(string message, Exception innerException) 

EntityDataSource Changes

1. The IncludePaths property has been renamed to Include

Affects:
       - ASP.NET users

SP1 Beta Code:
The property IncludePaths was used to specify which navigation propreties should be included in the query.

SP1 RTM Code:
The property name has changed to “Include”.

2. Public Methods removed from the EntityDataSourceView class

The following methods were removed from the EntityDataSourceView class

public String DefaultOrderByClause { get; }
public void DisposeContext();
public static Boolean EnumerableContentEquals( IEnumerable enumerableA,  IEnumerable enumerableB);

3. Event argument class APIs have changed

The event argument classes for the EntityDataSource have been re-architected to provide better usability.

Affects:
   ASP.NET users

  • ContextCreating

          SP1 Beta Code:

public class EntityDataSourceContextEventArgs : EventArgs
{
 // Methods
 public EntityDataSourceContextEventArgs();

 // Properties
 public ObjectContext Context { get; set; }
}

          SP1 RTM Code:

public class EntityDataSourceContextCreatingEventArgs : EventArgs
{
 public ObjectContext Context { get; set; }
}

  • ContextCreated

          SP1 Beta Code:

public class EntityDataSourceStatusEventArgs : EventArgs
{
}

          SP1 RTM Code:

public class EntityDataSourceContextCreatedEventArgs : EventArgs
{
  public ObjectContext Context { get; }
}

  • ContextDisposing

          SP1 Beta Code:

public class EntityDataSourceDisposeEventArgs : CancelEventArgs
{
 public object Context { get; }
}

          SP1 RTM Code:

public class EntityDataSourceContextDisposingEventArgs : CancelEventArgs
{
 public ObjectContext Context { get; }
}

  • Selecting

          SP1 Beta Code:

public class EntityDataSourceSelectEventArgs : CancelEventArgs
{
 public DataSourceSelectArguments Arguments { get; }
 public ParameterCollection CommandParameters { get; }
 public string CommandText { get; set; }
 public ObjectContext Context { get; }
 public string OrderBy { get; }
 public ParameterCollection OrderByParameters { get; }
 public string Where { get; }
 public ParameterCollection WhereParameters { get; }
}

          SP1 RTM Code:

public class EntityDataSourceSelectingEventArgs : CancelEventArgs
{
 public EntityDataSource DataSource { get; }
 public DataSourceSelectArguments SelectArguments { get; }
}

  • Selected

          SP1 Beta Code: 
          See EntityDataSourceStatusEventArgs

          SP1 RTM Code:

 public class EntityDataSourceSelectedEventArgs : EventArgs
{
    public ObjectContext Context { get; }
 public Exception Exception { get; }
 public bool ExceptionHandled { get; set; }
 public IEnumerable Results { get; }
 public DataSourceSelectArguments SelectArguments { get; }
 public int TotalRowCount { get; }
}

  • Updating

          SP1 Beta Code:

public class EntityDataSourceUpdateEventArgs : CancelEventArgs
{
 public Exception Exception { get; }
 public bool ExceptionHandled { get; set; }
 public object NewEntity { get; }
 public object OriginalEntity { get; }
}

          SP1 RTM Code:

public class EntityDataSourceChangingEventArgs : CancelEventArgs
{
  public ObjectContext Context { get; }
 public object Entity { get; }
 public Exception Exception { get; }
 public bool ExceptionHandled { get; set; }
}

  • Updated

          SP1 Beta Code:
          See EntityDataSourceStatusEventArgs

          SP1 RTM Code:

public class EntityDataSourceChangedEventArgs : EventArgs
{
 public ObjectContext Context { get; }
 public object Entity { get; }
 public Exception Exception { get; }
 public bool ExceptionHandled { get; set; }
}

  • Inserting

          SP1 Beta Code:

public class EntityDataSourceInsertEventArgs : CancelEventArgs
{
 public Exception Exception { get; }
 public bool ExceptionHandled { get; set; }
 public object NewEntity { get; set; }
 public IDictionary Values { get; }
}

          SP1 RTM Code:
          See EntityDataSourceChangingEventArgs

  • Inserted

          SP1 Beta Code:
          See EntityDataSourceStatusEventArgs

          SP1 RTM Code:
          See EntityDataSourceChangedEventArgs

  • Deleting

          SP1 Beta Code:

public class EntityDataSourceDeleteEventArgs : CancelEventArgs
{
 public EntityDataSourceValidationException Exception { get; }
 public bool ExceptionHandled { get; set; }
 public object OriginalEntity { get; }
}

          SP1 RTM Code:
          See EntityDataSourceChangingEventArgs

  • Deleted

          SP1 Beta Code:
          See EntityDataSourceStatusEventArgs

          SP1 RTM Code:
          See EntityDataSourceChangedEventArgs

Tools Changes

1. Namespace generation has changed

Existing EDMX files will be affected as soon as you make a change, open/save/close it, “Run Custom Tool” or move the EDMX file into a project sub-folder.

In SP1 beta the data classes were generated into a separate top level CSDL model namespace and users were forced to import the CLR namespace or fully qualify the class names in order to consume the generated data classes. The following changes were made in the RC based on feedback from users:

  • The Model Namespace specified in the wizard GUI has nothing to do with the CLR namespace of the generated data classes
  • The data classes are generate into a CLR namespace determined by the Visual Studio project system (based project type and the project sub-folder containing the EDMX file)
  • The designer respects the value of the Custom Tool Namespace project item property (if set)

Note: EDMX files in VB projects with an empty root namespace or in App_Code root in ASP.NET website projects continue to have the Beta 1 behavior for generated classes (i.e.  data classes are generated into a separate top level CSDL model namespace)

Code consuming the model is affected as follows:

  1. VB projects with an empty root namespace and ASP.NET website apps with EDMX files in App_Code root: no change since SP1 beta
  2. All other projects where the EDMX file is in the project root:

    a. SP1 Beta C# code example:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using NorthwindModel;
    
    namespace ConsoleApplication1
    {
     class Program
     {
     static void Main(string[] args)
     {
     using (NorthwindEntities entities = 
                           new NorthwindEntities())
     {
     foreach (Customers c in entities.Customers)
     Console.WriteLine(c.ContactName);
     }
     }
     }
    }

    b. SP1 RTM C# code example (note we don’t need the “using NorthwindModel;” anymore):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication1
    {
     class Program
     {
     static void Main(string[] args)
     {
     using (NorthwindEntities entities = 
                           new NorthwindEntities())
     {
     foreach (Customers c in entities.Customers)
     Console.WriteLine(c.ContactName);
     }
     }
     }
    }
    
  3. SP1 RTM C# code example for all projects where the EDMX file is in a project sub-folder (e.g. MyModels). Note the “using ConsoleApplication1.MyModels;”  below:
    PrFont34Bin0BinSub0Frac0Def1Margin0Margin0Jc1Indent1440Lim0Lim1using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using ConsoleApplication1.MyModels;
    
    namespace ConsoleApplication1
    {
     class Program
     {
     static void Main(string[] args)
     {
     using (NorthwindEntities entities = 
                     new NorthwindEntities())
     {
     foreach (Customers c in entities.Customers)
     Console.WriteLine(c.ContactName);
     }
     }
     }
    }
  4. In all projects, multiple EDMX files in the same project sub-folder cannot have duplicate entity or container names. Conflicts in generated classes (if any) can be resolved in one of the following ways:

a. For C# projects: Move the EDMX files into different project sub-folders folders or set the “Custom Tool Namespace” to a unique namespace

b. For ASP.NET website projects: Move the EDMX files into different project sub-folders folders under App_Code

c. For VB projects: Set the “Custom Tool Namespace” to a unique namespace

We have just updated a number of Entity Framework samples, including two sample providers, to work with the .NET Framework 3.5 and Visual Studio 2008 SP1 released today. Most updates were cosmetic, but there are some major changes too.

  1. EFQuerySamples - Entity Framework Query Samples
    This sample has been updated to provide for better maintainability and added support for multiple providers. This means that the same queries can be executed against different databases and providers. The version that we have released supports 6 backends, but it's trivial to add new ones (the README file that comes with the sample has instructions on doing that). Currently supported are: SqlClient (running against SQL Server 2000, 2005 and 2008), SQL Server Compact Edition 3.5 SP1, EFSampleProvider and EFOracleProvider.

    We've also added ability to run all samples at once (for example in a batch file) and save results to a file, which can be useful when developing your own provider. The command line used to run all samples against EFOracleProvider and store results in a text file called log.txt would look like:

    SampleQueries.exe /logfile log.txt /connectionString "NorthwindEF (EFOracleProvider)" /runall 
  2. EdmMetadataSamples - EDM Metadata Samples
    No major changes in the code, just some general project cleanup - C# and VB projects have now been merged and database setup has changed. If you haven't seen this sample, check it out - it allows you to browse any EDM Model in a graphical way using ASP.NET and to do simple queries. 
  3. EFSampleProvider - Entity Framework Sample
    Provider Changes in reaction to public API cleanup:
      - Removed DbProviderManifest.Token and DbProviderManifest.Provider properties
      - Removed DbFunctionExpression.IsLambda
      - Renamed DbFunctionCommandTree.Function to DbFunctionCommandTree.EdmFunction
      - Removed DbCommandTree.Validate()
      - Added support for missing canonical function CurrentDateTime(). 
  4. EFOracleProvider - Entity Framework Sample Provider for Oracle
    Changes to react to public API cleanup:
      - Removed DbProviderManifest.Token and DbProviderManifest.Provider properties
      - Removed DbFunctionExpression.IsLambda
      - Renamed DbFunctionCommandTree.Function to DbFunctionCommandTree.EdmFunction
      - Removed DbCommandTree.Validate() 
  5. EFLazyLoading - Transparent Lazy Loading for Entity Framework
    Automatically generated code is no longer part of the sample. Instead it is generated as part of every build.

Check back as we continue to update the remainder of our Entity Framework samples over the coming weeks.

 

Jaroslaw Kowalski
SDET, ADO.NET Entity Framework

Visual Studio 2008 SP1 introduces significant new functionality as ADO.NET expands and evolves to change the way that we program against data.

Between the Visual Studio 200 SP1 beta and RTM , there are a number of fixes and even a few new things to be found. What's in ADO.NET? Check out the list below for what's new in the Entity Framework and Entity Designer.

 

Entity Framework Runtime

Object Services

  • Navigation properties are exposed as property descriptors and are available for data binding ObjectQuery results in WinForms and WPF applications.
  • More consistent handling of available data binding property descriptors that are not dependent on the query result.
  • The RelationshipSet for an EntityCollection or EntityReference is exposed on these classes.
  • IRelatedEnd.IsLoaded property now correctly reflects the state of the relationship after MergeOption.PreserveChanges and MergeOption.OverwriteChanges queries.
  • Entities that self-reference can now be used with Attach and AttachTo

EntityDataSource

  • Event model for the EntityDataSource has been updated. See the Visual Studio 2008 SP1 Breaking Changes post for details on the new event classes.
  • Null values are supported on primitive type columns
  • Data bound controls can now sort on each field
  • Ability to “Refresh Schema” from data bound controls through the Visual Studio ASP.NET page designer now provides an error report in cases where the query cannot be executed successfully.
  • Parameter.DbType is now supported with parameters to the EntityDataSource.
  • EntityDataSource design time experience now uses standard mechanisms to locate and load metadata assemblies. This requires the metadata assembly to be built prior to the EntityDataSource configuration wizard to locate the assembly.

Entity Designer

Between the last beta and RTM we fixed well over 200 bugs across multiple areas in the Entity Designer. Most notably, the undo/redo performance for common operations (e.g. creation and deletion of entities)  and “Update Model from Database” performance have been significantly improved. Here’s a bird’s eye view of some of the other things we’ve made better:

  • Improved layout performance when using “Update Model from Database”
  • Support for panning the diagram with the mouse scroll wheel
  • Zoom level is correctly saved after undo/redo and when the EDMX file is saved
  • Fixed various accessibility and high contrast bugs
  • Source control: EDMX file written out by the designer is formatted better than before to alleviate many issues with merging in source control scenarios
  • Source control: App.Config is now checked out correctly when the wizard tries to add a connection string to it
  • Source control: Custom Tool is no longer empty after Getting EDMX file from SourceSafe in ASP.NET website project
  • F1 help is integrated with MSDN online
  • Building a Project with an EDMX file in solution with a Setup project works correctly
  • Validation: correctly accounts for RI constraints
  • Validation: fixed incorrect error message when types are mapped with condition
  • Validation: fixed incorrect designer validation error when there’s no run-time error
  • Validation: accounts for multiple conditions in mapping
  • Validation: conditions on abstract types correctly validated
  • The “Create Function Import” dialog has been improved

Today we announced the release of the ADO.NET Entity Framework and ADO.NET Data Services in the Visual Studio 2008 SP1 and the .NET Framework 3.5 SP1.

With this release, many database providers have pledged support for the Entity Framework. To date, 12 provider writers are developing an Entity Framework-enabled version of their offerings that are scheduled to be made publicly available in the coming months.

"DataDirect Technologies is delighted to see the ADO.NET Entity Framework RTM," said John Goodson, vice president and general manager of DataDirect Technologies.  "We are firmly committed to the ADO.NET Entity Framework and look forward to offering Oracle connectivity in the near future."

Providers Planning Publicly Available Versions in 2008 (Q3 & Q4 CY2008)

  • Devart (formerly Core Lab) - Providing connectivity to Oracle, MySQL, PostgreSQL and SQLite databases
  • Firebird - Providing connectivity to Firebird databases
  • IBM - Providing connectivity to both IBM DB2 data server and Informix Dynamic Server (IDS) database
  • Npgsql - Providing connectivity to PostgreSQL database versions 7.3+ and 8.x
  • OpenLink Software - Providing connectivity to OpenLink Virtuoso, Oracle, Informix, Ingres, Sybase, MySQL, PostgreSQL, DB2, Progress and Microsoft SQL Server databases, and any data source accessible via OpenLink ODBC or JDBC bridge drivers
  • Phoenix Software Solutions - Providing connectivity to SQLite databases
  • Sun Microsystems - Providing connectivity to MySQL databases
  • Sybase - Providing connectivity to SQL Anywhere databases
  • VistaDB Software - Providing connectivity to VistaDB database

Providers Planning Publicly Available Versions in Early 2009 (Q1 CY2009)

  • Synergex - Providing connectivity to Synergy/DE databases

Providers Committed to Supporting the Entity Framework

  • DataDirect Technologies - Providing connectivity to multiple data stores including Oracle, Sybase, Microsoft SQL Server and DB2 via DataDirect Connect® for ADO.NET

The Entity Framework and the Entity Designer have Released! Today marks the official RTM of Visual Studio 2008 SP1 and the .NET Framework 3.5 SP1, and we are thrilled to announce the official RTM of the ADO.NET Entity Framework, the ADO.NET Entity Designer and ADO.NET Data Services.

The Entity Framework and Data Services raise the level of abstraction for database programming and supply both a new model-based paradigm and a rich, standards-based framework for creating data-oriented Web services. Powered by rich and integrated tooling, the new ADO.NET Entity Designer lets users instantly leverage the new model-based paradigm in their applications. With the ADO.NET Entity Designer, users can generate models & mappings from an existing database and also create models with complex inheritance hierarchies & mappings in an intuitive, easy to use graphical user interface well integrated with Visual Studio 2008 SP1. The new Entity Data Source Control lets users consume models in their web applications with ease.

EscherRTM_JPG

With this service pack, Visual Studio 2008 and the .NET Framework 3.5 also support SQL Server 2008, making the Microsoft platform the most comprehensive environment for database application development. You can find more information on both of these technologies and download SP1 at http://msdn.microsoft.com/data

Stay tuned for more posts covering updates and changes made between the SP1 Beta and RTM.

 

- ADO.NET Team

More Posts Next page »
 
Page view tracker