EDM Changes

 

1.       CommandText attribute on Function element in SSDL schema has been changed to a child Element.

 

Mitigation

 If you used the CommandText attribute on Function elements, change it to a Child Element.

 

Beta 2 Code

<Function Name="InsertProduct" IsComposable="false" CommandText="Insert Products ...">

 

Beta 3 Code

<Function Name="InsertProduct" IsComposable="false" >  <CommandText>Insert Products ...</CommandText>

 

2.       Changed all Enumeration values in Schema Files to have Pascal Casing so that they are consistent.

 

Mitigation

Change the SchemaFiles to reflect the new values.

 

Csdl Changes

Area

Beta 2

Beta 3

DateTimeKind

UTC

Utc

Mode

in

In

Mode

out

Out

Mode

inout

InOut

ConcurrencyMode

none

None

ConcurrencyMode

fixed

Fixed

MaxLength

max

Max

 

Ssdl Changes

Area

Beta 2

Beta 3

DateTimeKind

UTC

Utc

Mode

in

In

Mode

out

Out

Mode

inout

InOut

StoreGeneratedPattern

none

None

StoreGeneratedPattern

identity

Identity

StoreGeneratedPattern

computed

Computed

MaxLength

max

Max

 

ProviderManifest Changes

Area

Beta 2

Beta 3

Mode

in

In

Mode

out

Out

Mode

inout

InOut

CSMapping Changes

Area

Beta 2

Beta 3

Version

original

Original

Version

current

Current

 

CodeGeneration Changes

Area

Beta 2

Beta 3

Access

public

Public

Access

internal

Internal

Access

private

Private

Getter/Setter

public

Public

Getter/Setter

internal

Internal

 

 

3.       GetMappedPrimitiveType method on MetadataWorkspace and ItemCollection class has been removed.

 

      Beta 2 Code

   PrimitiveTypeKind edmType = ((PrimitiveType)  

   sourceProperty.Type.EdmType).PrimitiveTypeKind;

   PrimitiveType sqlType = workspace.GetMappedPrimitiveType(edmType, 

   DataSpace.SSpace);

 

      Beta 3 Code

   TypeUsage edmType =   sourceProperty.TypeUsage;

   EntityConnection connection = context.Connection as EntityConnection;

   DbProviderServices services = DbProviderServices.CreateProviderServices 

   (connection.StoreConnection);

   DbProviderManifest manifest = services.GetProviderManifest 

   (connection.StoreConnection);

   TypeUsage sqlType = manifest.GetStoreType(edmType);

 

4.       StoreItemCollection that is Constructed over SqlConnection needs an Open or Openable connection. Previously a non-null SqlConnection would have worked even if it could not be opened.

 

Mitigation

If you were previously using a SqlConnection that was not openable and you don't prefer the provider to open a connection, you would need to use a new Constructor added to the StoreItemCollection that takes in DBProviderFactory instead of DBConnection. This would only work if the SSDL file passed into the constructor had a ProviderManifestToken attribute added to the Schema element.

 

Beta 2 Code

storeItemCollection = new StoreItemCollection( new SqlConnection(), ssdlFilePath);

 

Beta 3 Code

storeItemCollection = new StoreItemCollection(SqlClientFactory.Instance, ssdlFilePath);

 

5.       Unsigned types have been removed from EDM/CSDL type system.

 

Mitigation

No mitigation for this.

 

Entity Services Changes

 

6.       Obtaining the native SQL generated for a given command has changed. EntityCommand - DbProviderServices.CreateCommandDefinition, ObjectQuery.CreateCommandTree() and DbProviderServices.CreateCommandDefinition are no longer available

 

Mitigation

There is a new, simpler, pattern. Use EntityCommand.ToTraceString() or ObjectQuery.ToTraceString().

 

Beta 2 Code

string esql = "SELECT VALUE product \n" +
              "FROM Northwind.Products AS product\n" +
              "WHERE LEFT(product.ProductName, 1) = 'C' \n" +
              "ORDER BY product.ProductName";
EntityCommand productsCmd = connection.CreateCommand();
productsCmd.CommandText = esql;
connection.Open();
productsCmd .Prepare();

IServiceProvider serviceProvider = (IServiceProvider)EntityProviderFactory.Instance;
DbProviderServices providerServices = (DbProviderServices)serviceProvider.GetService(typeof(DbProviderServices));
EntityCommandDefinition commandDefinition = (EntityCommandDefinition)providerServices.CreateCommandDefinition(productsCmd );

foreach (string commandText in commandDefinition.MappedCommands)
{
    Console.WriteLine(commandText);
}

 

Beta 3 Code

// For EntityCommand

string esql = "SELECT VALUE product \n" +
              "FROM Northwind.Products AS product\n" +
              "WHERE LEFT(product.ProductName, 1) = 'C' \n" +
              "ORDER BY product.ProductName";
EntityCommand productsCmd = connection.CreateCommand();
productsCmd.CommandText = esql;
connection.Open();
Console.WriteLine(productsCmd.ToTraceString());

 

// For ObjectQuery

ObjectQuery<Northwind.Product> products = northwind.Products
        .Where("LEFT(it.ProductName, 1) = 'C'")
        .OrderBy("it.ProductName");
northwind.Connection.Open();
Console.WriteLine(products.ToTraceString());

 

 

7.       Canonical function Edm.Length() ignores trailing white space when connected to SQL Server (any version).

 

Mitigation

Previously Edm.Length() was trying to include trailing spaces. Starting with Beta 3 it maps directly to SqlServer.Len() which ignores trailing spaces. Consider trimming trailing white space on literals and properties before sending them down the pipeline.

 

Beta 2 Code

Edm.Length('abc ')
-- T-SQL: LEN('abc ' + '.') - LEN('.')
-- Returns: 4

 

Beta 3 Code

Edm.Length('abc ')

-- T-SQL: LEN('abc ')

-- Returns: 3

 

LINQ to Entities Changes

 

8.       Group By can no longer be applied on a navigation property

 

Mitigation

Add the key properties of the related entity to the query after the navigation property.

 

Beta 2 Code


var query = from p in context.Products
    group p by p.Category into g
    select new
           {
               CategoryID = g.Key,
               AveragePrice = g.Average(p=>p.UnitPrice)
           };
 

 

Beta 3 Code


var query = from p in context.Products
    group p by p.Category.CategoryID into g
    select new
           {
               CategoryID = g.Key,
               AveragePrice = g.Average(p=>p.UnitPrice)
           };

 

Object Services Changes

 

9.       ObjectStateManager.GetObjectStateEntry() no longer accepts an entity object instance as a parameter

 

Mitigation

Pass an EntityKey instead.

 

Beta 2 Code


var order = context.Orders.First();

var state = context.ObjectStateManager.GetObjectStateEntry(order);

 

Beta 3 Code


var order = context.Orders.First();

var state = context.ObjectStateManager.GetObjectStateEntry(order.EntityKey);

 

10.   ObjectQuery.First(), -FirstOrDefault(), and -Exists() have been removed.

 

Mitigation

Use the LINQ to Entities implementation through IQueryable.

 

Beta 2 Code

Product product = northwind.Products.First();

 

Beta 3 Code

using System.Linq;

 

Product product = northwind.Products.First();

 

11.   ObjectQuery.Parameters collection is locked once the query is compiled/executed.

 

Mitigation

Ability to add or remove paramters to the parameter collection once the query is  compiled was an error. Now Entity Framework explicitly throws on such attempts.
Note: values of existing parameters may be changed, and subsequent executions of the query will use the new values.

 

Beta 2 Code

ObjectQuery<Product> products = northwind.Products
         .Where("it.ProductName LIKE @startsWith + '%'")
         .OrderBy("it.ProductName");
products.Parameters.Add(new ObjectParameter("startsWith", "C"));
foreach (Northwind.Product product in products)
{
    Console.WriteLine("{0,2}: {1}", product.ProductID, product.ProductName);
}
products.Parameters.Add(new ObjectParameter("foo", "ABC"));
// The above statement passes

 

Beta 3 Code

ObjectQuery<Product> products = northwind.Products
        .Where("it.ProductName LIKE @startsWith + '%'")
        .OrderBy("it.ProductName");
products.Parameters.Add(new ObjectParameter("startsWith", "C"));
foreach (Northwind.Product product in products)
{
    Console.WriteLine("{0,2}: {1}", product.ProductID, product.ProductName);
}
products.Parameters.Add(new ObjectParameter("foo", "ABC"));
// The above statement throws InvalidOperationException

 

 

12.   EntityKey.EntityKeyValues has changed from ReadOnlyCollection<KeyValuePair<string, object>> to EntityKeyMember[].

 

Mitigation

An EntityKeyMember is a KeyValuePair that can be serialized using Xml serialization. It contains both a string key name and an object key value.

 

13.   ObjectContext no longer opens a connection during the constructor.

 

Mitigation

The ObjectContext class no longer opens the underlying EntityConnection as part of the constructor call. As a result, the MetadataWorkspace that is returned from the MetadataWorkspace property will not contain the SSpace and CSSpace metadata immediately. These metadata collections will be available the first time the ObjectContext opens the underlying EntityConnection.

 

14.   EntityKey class no longer implements IXmlSerializable

 

Mitigation

The EntityKey class is still serializable using the XmlSerializer, but uses public properties rather than an explicit implementation of IXmlSerializable.

 

15.   EntityKey(EntitySet entitySet, IEnumerable<KeyValuePair<string, object>> entityKeyValues) constructor has been removed.

 

Mitigation

Use an alternative constructor.

Beta 2 Code

EntityKey key = new EntityKey(entitySet, keyValues);

 

Beta 3 Code

EntityKey key = new EntityKey(entitySet.EntityContainer.Name + "." + entitySet.Name, keyValues)

 

16.   EntityKey(string qualifiedEntitySetName, string[] keyNames, object[] keyvalues) constructor has been removed

 

Mitigation

Use an alternative constructor such as

 

Beta 2 Code

EntityKey key = new EntityKey("EC.ES", new string[] {"K1", "K2"}, new object[] {key1, key2});

 

Beta 3 Code

EntityKey key = new EntityKey("EC.ES", new EntitykeyMember[] {

new EntityKeyMember("K1", key1),

new EntityKeyMember("K2", key2)});

 

17.   ObjectStateManager.GetEntityKey(object) has been removed.

 

Mitigation

To get an EntityKey for an object instance, call ObjectContext.GetEntityKey(entitySetName, object). This key can then be used to lookup an ObjectStateEntry in the ObjectStateManager to determine if the object is being tracked.

 

Beta 2 Code

EntityKey key = stateManager.GetEntityKey(object);

 

Beta 3 Code

EntityKey key = context.GetEntityKey(entitySetName, object);

 

18.   EntityCollection.CollectionChanged event has been renamed to AssociationChanged

 

Mitigation

Use the AssociationChanged event instead of the CollectionChanged event

 

Beta 2 Code

collection.CollectionChanged += handler;

 

Beta 3 Code

collection.AssociationChanged += handler;

 

19.   ObjectQuery IListSource implementation is explicitly implemented.

 

Mitigation

You will need to cast the ObjectQuery to an IListSource before calling ContainsListCollection property or the GetList method.

 

Beta 2 Code

IList list = query.GetList();

 

Beta 3 Code

IList list = ((IListSource)query).GetList();

 

20.   ObjectContext.Refresh no longer takes a params array of objects to refresh.

 

Mitigation

The overloads for Refresh include one that takes a single object to refresh, as well as one that takes an IEnumerable of objects to refresh.

 

Beta 2 Code

ctx.Refresh(RefreshMode.ServerWins, o1, o2, o3);

 

Beta 3 Code

ctx.Refresh(RefreshMode.ServerWins, new object[] {o1, o2, o3});

 

21.   ObjectQuery.GetResultType() requires the user to open the connection.

 

Mitigation

The GetResultType() call requires that the user have the CSSpace and SSpace metadata collections loaded into the ObjectContext's MetadataWorkspace. To do this, the ObjectContext's connection must have opened at some point. The connection can be forced to open by calling ctx.Connection.Open().

 

Tools Changes

 

22.   EDMX files created in CTP1 don't always open in CTP2 of the designer

 

Mitigation

The file format of .edmx files has changed in CTP2. Opening .edmx files created with earlier versions of the designer is not supported.

To resolve this issue:
Recreate the .edmx file in CTP2 of the designer.

 

23.   Build error when projects with .edmx files created in Visual Studio Beta 2 and EDM Designer CTP 1 are rebuilt in Visual Studio 2008 RTM

 

Mitigation

Projects with .edmx files created in earlier CTPs had a reference to EdmxDeploy.exe in the project post-build event. Building such projects in VS 2008 RTM causes a build failure with a message that EdmxDeploy.exe cannot be found.

To resolve this issue:
The functionality provided by EdmxDeploy.exe is now available in the EntityDeploy MSBUILD task. Modify the post-build event in project properties and remove the reference to EdmxDeploy.exe