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.
Change the SchemaFiles to reflect the new values.
Csdl Changes
Area
Beta 2
Beta 3
DateTimeKind
UTC
Utc
Mode
in
In
out
Out
inout
InOut
ConcurrencyMode
none
None
fixed
Fixed
MaxLength
max
Max
Ssdl Changes
StoreGeneratedPattern
identity
Identity
computed
Computed
ProviderManifest Changes
CSMapping Changes
Version
original
Original
current
Current
CodeGeneration Changes
Access
public
Public
internal
Internal
private
Private
Getter/Setter
3. GetMappedPrimitiveType method on MetadataWorkspace and ItemCollection class has been removed.
PrimitiveTypeKind edmType = ((PrimitiveType)
sourceProperty.Type.EdmType).PrimitiveTypeKind;
PrimitiveType sqlType = workspace.GetMappedPrimitiveType(edmType,
DataSpace.SSpace);
TypeUsage edmType = sourceProperty.TypeUsage;
EntityConnection connection = context.Connection as EntityConnection;
DbProviderServices services = DbProviderServices.CreateProviderServices
(connection.StoreConnection);
DbProviderManifest manifest = services.GetProviderManifest
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.
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.
storeItemCollection = new StoreItemCollection( new SqlConnection(), ssdlFilePath);
storeItemCollection = new StoreItemCollection(SqlClientFactory.Instance, ssdlFilePath);
5. Unsigned types have been removed from EDM/CSDL type system.
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
There is a new, simpler, pattern. Use EntityCommand.ToTraceString() or ObjectQuery.ToTraceString().
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);}
// 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).
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.
Edm.Length('abc ') -- T-SQL: LEN('abc ' + '.') - LEN('.')-- Returns: 4
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
Add the key properties of the related entity to the query after the navigation property.
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) };
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
Pass an EntityKey instead.
var order = context.Orders.First();
var state = context.ObjectStateManager.GetObjectStateEntry(order);
var state = context.ObjectStateManager.GetObjectStateEntry(order.EntityKey);
10. ObjectQuery.First(), -FirstOrDefault(), and -Exists() have been removed.
Use the LINQ to Entities implementation through IQueryable.
Product product = northwind.Products.First();
using System.Linq;
11. ObjectQuery.Parameters collection is locked once the query is compiled/executed.
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.
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
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[].
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.
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
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.
Use an alternative constructor.
EntityKey key = new EntityKey(entitySet, keyValues);
EntityKey key = new EntityKey(entitySet.EntityContainer.Name + "." + entitySet.Name, keyValues)
16. EntityKey(string qualifiedEntitySetName, string[] keyNames, object[] keyvalues) constructor has been removed
Use an alternative constructor such as
EntityKey key = new EntityKey("EC.ES", new string[] {"K1", "K2"}, new object[] {key1, key2});
EntityKey key = new EntityKey("EC.ES", new EntitykeyMember[] {
new EntityKeyMember("K1", key1),
new EntityKeyMember("K2", key2)});
17. ObjectStateManager.GetEntityKey(object) has been removed.
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.
EntityKey key = stateManager.GetEntityKey(object);
EntityKey key = context.GetEntityKey(entitySetName, object);
18. EntityCollection.CollectionChanged event has been renamed to AssociationChanged
Use the AssociationChanged event instead of the CollectionChanged event
collection.CollectionChanged += handler;
collection.AssociationChanged += handler;
19. ObjectQuery IListSource implementation is explicitly implemented.
You will need to cast the ObjectQuery to an IListSource before calling ContainsListCollection property or the GetList method.
IList list = query.GetList();
IList list = ((IListSource)query).GetList();
20. ObjectContext.Refresh no longer takes a params array of objects to refresh.
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.
ctx.Refresh(RefreshMode.ServerWins, o1, o2, o3);
ctx.Refresh(RefreshMode.ServerWins, new object[] {o1, o2, o3});
21. ObjectQuery.GetResultType() requires the user to open the connection.
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
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
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