Download

Get the code on Github

breeze.debug.js
breeze.min.js

Get started

Start with NuGet
This is the easiest way to build a Breeze application if you are using Visual Studio.

Github
The Breeze source code is free, open-source, MIT licensed, and hosted on GitHub.

Prerequisites

Many of the demos and samples were built with .NET development in mind. Please review the prerequisites topic before trying to build and execute them.

Release notes

Pre-1.4.x builds and release notes are also available.

1.4.x

1.4.11 Mar 7, 2014

Features

  • Performance improvements with large saves and large queries that overwrite existing modified entities.
  • New Web API OData Sample, an MVC/SPA hybrid written with Javier Calvarro Nelson, a member of the Microsoft Web API OData team. This effort prompted numerous small changes to Breeze core that enriched exposed functionality w/o changing underlying behavior.
  • The Angular Todo Sample has been spruced up. It's been upgraded to Angular v.1.2 and the new "Breeze Angular Service" module.
  • Breeze 'ajax' adapters accept headers configuration; useful to authors of Breeze 'dataService' adapters.
  • EntityQuery.fromEntityKey specifically targets the EntityType of the EntityKey and casts query results into that EntityType.

  • New or changed in Breeze Labs

    • Breeze Angular Service, a new breeze.angular.js module that configures your Breeze/Angular client app for Angular in "Angular-style". Sets the right 'model library', $q for promises, and $http for ajax calls. It has its own nuget package.

    • getEntityGraph extends EntityManager so you can retrieve a root entity and its related entities from cache as an array. Read why and how in the breeze labs documentation.

    • metadata-helper (updated) library to make hand-coding Breeze metadata in JavaScript a bit easier. Now a nuget package.

    • EdmBuilder, a tiny C# class that generates Breeze-compatible metadata for a Web API OData backend. See the Web API OData sample.

    • SharePoint 2013 + Angular + Breeze - a composite nuget package that delivers in one package all the Breeze stuff you need to build the app. We're really close to announcing a SharePoint/Angular/Breeze sample built by Andrew Connell.

    • SharePoint 2013 OData DataService Adapter, included in the SharePoint/Angular package, this is independent of Angular and therefore suitable for a Breeze application that doesn't use Angular. Best acquired from nuget.

    • breeze.directives.validation is in the middle of a rewrite to enable richer options for developer configuration. The code has changed, the behavior ... not yet (at least not intentionally).

    • Angular.MidwayTester - a nuget package, delivering Matias Niemelä's Angular test library (with his kind permission) for async testing. Great for testing that your Breeze client is talking to your server in the ways you expect.

  • Deprecated in Breeze Labs

    • breeze.angular.q - use the "Breeze Angular Service" instead
    • to$q - de-documented; use "Breeze Angular Service"

Bugs

  • ( v 1.4.9 - removed and replaced with this version)
  • Fixed bug involving fixup of unidirectional multipart keys.
  • Fixed regression bug introduced in 1.4.9 involving multipart key fixup after save.
  • Chrome 33/Minification bug - Can't repro this bug but we think this is the fix...
  • Fixed bug where queries with MergeStrategy.OverwriteChanges were not firing EntityStateChange events.
  • Fixed bug with EntityManager.fetchEntityByKey when metadata had not yet been fetched.
  • Fixed bug with EntityAspect.getValidationErrors and complex property names.
  • Fixed bug with failed promise handling ( edge condition).
  • Misc Api Documentation fixes.
  • NHibernate: Fixed bug with $expands on subclasses.
  • NHibernate: Fixed bug with save order when saving related entities.
  • NHibernate: Fixed bug with deletes and one-to-one mappings.
  • NHibernate: Fixed bug with saving when foreign key references identifier of derived class.
  • NHibernate: Added missing invForeignKeyNamesOnServer to metadata.
  • NHibernate: Fixed bug with unchanged entites in saveMap. Now they get related but not saved.
  • NHibernate: Changed NHContext method signatures from private to protected to ease overriding of SaveChangesCore by subclasses.

Breaking changes

  • None

1.4.8Jan 7, 2014

Features

  • Updated Breeze-MongoDB npm package ( version: 0.0.6).
    • Support for queries using FilterQueryOp.Any and FilterQueryOp.All in MongoDB.
  • NHibernate support for Web API 2
    • Including two new NuGet packages: Breeze.WebApi2.NH and Breeze.Server.ContextProvider.NH
  • Improved JSON serialization performance for NHibernate for both Web API and Web API 2.

Bugs

  • Corrected issue where Breeze tries to load Angular with RequireJS when it shouldn't.
  • Metadata resolution fix to remove inadvertent dependence on foreign key naming conventions.
  • Fixed bug with query filters against Int64 fields.
  • Fixed bugs with query filters using OData numeric and date functions not functioning properly for local queries.
    • For example: var p = Predicate.create("year(OrderDate)", Qop.Equals, 1996);
  • Fixed bugs with query filters involving searches for strings containing single quotes.
  • NHibernate specific WebApi/WebApi2 fixes:
    • Fixed error performing saves when foreign keys are defined on a base class.
    • Fixed bug that could cause NHibernate Session to be left open if an exception is thrown.
    • Breeze will now throw an exception when trying to save a entity with a key modification in EF, which EF prohibits. ( but may be permitted in other environments).
    • Fixed support for OData $expand expressions (bug was only present in WebApi2)
  • MongoDB specific fixes:
    • Fixed bug with EntityQuery 'top(0)' not working properly.
    • Fixed bug with query filters for strings containing single quotes.

Breaking changes

  • Breeze previously required that any single quotes within a query string be manually escaped within an EntityQuery. This is no longer required ( and will in fact cause the query to fail).

     // Old Code 
     var q = EntityQuery.from("Employees").where("lastName", "contains", "O''Malley");
     // should be converted to 
     var q = EntityQuery.from("Employees").where("lastName", "contains", "O'Malley");

1.4.7Dec 12, 2013

Features

Bugs

  • Fixed bug where Entity Framework key modification save errors were not being propagated to the Breeze client.
    • Breeze will now throw an exception when trying to save a entity with a key modification in EF, which EF prohibits. ( but may be permitted in other environments).
  • Fixed null reference exception that could occur in EntityAspect.getValidationErrors.
  • Fixed EntityManager.importEntities bug that would create originalValues changes when it should not.
  • Fixed bug with incorrect inlineCount in any EntityQuery involving the combination of the inlineCount, select, and top/skip methods.
  • Fixed bug where EntityAspect.setDeleted() would not clear a related entity relation when no inverse property was defined.
  • Fixed the EntityQuery.noTracking method to insure that the method always returns a cloned query. ( like all of the other EntityQuery builder methods).
  • Fixed IE8/ES5 property descriptor bug.

1.4.6Nov 23, 2013

Features

  • The ability to perform an EntityQuery involving the "any" or "all" operators ( also aliased as "some" and "every") has been added.

For more info see Entity Query Any/All conditions

+ An EntityQuery.noTracking method has been added to allow EntityQueries to return simple JavaScript objects instead of Breeze entities. The method accept a single optional boolean parameter that determines whether or not the noTracking capability should be enabled. If this parameter is omitted, true is assumed.

With 'noTracking' enabled, the results of the query  will not be coerced into entities but will instead look like raw JavaScript projections. i.e. simple JavaScript objects. However, the following "entity" services will still be performed

    a) graph cycle resolution
    b) property renaming
    c) datatype coercion

Note that any *EntityQuery.expand* will still work with 'noTracking' queries and will return parent entities with attached children all as simple js objects.

These objects will not be added to the EntityManager and will not be observable. However, as mentioned above, breeze cycle management and data type transformations will still occur.   Because they skip the cache-merging step, such queries *might* materialize significantly faster than a corresponding query without the 'noTracking' option. Your mileage may vary. 

Example:

    var query = EntityQuery
        .from("Orders")
        .where("customer.companyName", "startsWith", "C")
        .expand("customer")
        .noTracking();

    myEntityManager.executeQuery(query).then(function (data) {
        ...
    });
  • Two new MergeStrategies have been added: SkipMerge and Disallowed

    • SkipMerge is used to ignore incoming values. Adds the incoming entity to the cache only if there is no cached entity with the same key. This is the fastest merge strategy but your existing cached data will remain “stale”.
    • Disallowed is used to throw an exception if there is an incoming entity with the same key as an entity already in the cache. Use this strategy when you want to be sure that the incoming entity is not already in cache. This is the default strategy for EntityManager.attachEntity.
  • A MergeStrategy may now be passed into the EntityManager.createEntity and EntityManager.attachEntity methods as the last parameter.

  • Entity graphs are now supported when passing 'initialValues' to the EntityManager.createEntity, EntityManager.attachEntity, and EntityType.createEntity methods.

    This facility may be used in conjunction with the new EntityQuery.noTracking method when there is a need to convert a subset of the results of a noTracking query into entities and attach them to an EntityManager. For example:

    var empType = myEntityManager.metadataStore..getEntityType("Employee");
    var q = EntityQuery.from("Employees")
        .expand("orders")
        .noTracking()
        .using(myEntityManager);
    q.execute().then(data) {
        var rawEmps = data.results;
        emps = rawEmps.map(function (rawEmp) {
           emp = empType.createEntity(rawEmp);
           // emp has an entityAspect at this point but is not yet attached.
           empx = myEntityManager.attachEntity(emp, EntityState.Unchanged,MergeStrategy.SkipMerge);
           // empx may NOT be the same as emp because of the possibility that an emp
           // with the same key already exists within the EntityManager.
           return empx;
        });
    });    

The export/import features added in this release are documented in Exports and Imports.

  • The EntityManager.exportEntities method now allows you to optionally exclude metadata. This can significantly reduce the size of the exported data, especially when exporting only a small number of entities.

    • The EntityManager.exportEntities method now has a second boolean parameter, includeMetadata. It is optional and defaults to 'true'. Set this second parameter to false if you want to exclude metadata. Example:

      myEntityManager.exportEntities(entitiesToExport, false); // export without metadata

    Entities exported without metadata must be re-imported into an EntityManager that already contains the matching metadata or else an exception will be thrown.

  • The EntityManager.importEntities method has been extended to accept the import of exported entities without metadata. The 'config' parameter to this method has also been extended with an additional optional metadataVersionFn property. The property allows a developer to 'inject' a custom function to be executed as the first step of the import process to determine if the imported data is 'correct'. For example

    myEntityManager.importEntities(exportedEntities, {
        mergeStrategy: breeze.MergeStrategy.PreserveChanges,
        metadataVersionFn: function (cfg) {
            if (myEntityManager.metadataStore.name != cfg.metadataStoreName) {
                throw new Error("Incorrect store name")
            }
            if (breeze.metadataVersion != cfg.metadataVersion)   {
                throw new Error("Incorrect metadata version")
            }
        }
    });

  • An additional name property has been added to the MetadataStore. This allows a developer to 'name' a collection of metadata. This name is automatically included as part of the package resulting from any exportEntities method call and can be accessed during the execution of any importEntities call via the metadataVersionFn described above. The name property may be set via the MetadataStore.setProperties method.

    myEntityManager.metadataStore.setProperties({
        name: "Foo-17"
    });

The serialization features added in this release are documented in Entity Serialization.

  • When serializing data from the Breeze client to either the server or to an exported string, Breeze automatically ensures that exceptions do not occur during the serialization process. In practice this means ensuring that any 'unmapped' properties serialize 'correctly'. It does this according to the following rules:

    1) If the object being serialized has a property named toJSON whose value is a function, then the toJSON method customizes the JSON serialization behavior: instead of the object being serialized, the value returned by the toJSON method when called will be serialized. (This is the same function and behavior as is used by the JSON.stringify method).

    2) Functions are never serialized unless they have a toJSON function property.

    3) Objects that contain cycles have cyclical properties stubbed out at the point where a previously serialized node is encountered. As with functions, this behavior can be mediated with a toJSON implementation.

  • A new "serializerFn" property has been added to both the MetadataStore and the EntityType classes. This property, if present, mediates the entity serialization process. Note that the serialization rules from the item above are still applied AFTER the serializerFn executes.

    The 'serializerFn' takes two arguments: a DataProperty, and a value. The return value of the function determines what gets serialized for the specified property. If an 'undefined' is returned then the serialization of that property is suppressed.

    The MetadataStore.setProperties method and the EntityType.setProperties methods are used to set this property.

    As as example, the following code suppresses the serialization of all 'unmapped' properties.

    myEntityManager.metadataStore.setProperties({
      serializerFn: function (dataProperty, value) {
           return dataProperty.isUnmapped ? undefined : value;
      }
    }); 

  • .NET Exceptions thrown on the server are now available in their original form in the httpResponse.data property of any async breeze result. Previously Breeze would rethrow some server exceptions in order to provide a better client side error message. Breeze will still drill down to extract a "good" error message, but will no longer obscure the initial exception.

Bug fixes

  • Fix for bug where the EntityManager.createEntity method could not handle a config with nested complex types.
  • Fix for bug where Entity Framework metadata for default values was not setting the corresponding client side metadata defaultValues.
  • Nonscalar complex properties can now be serialized successfully via EntityManager.exportEntities

Breaking Changes

None

1.4.5Oct 28, 2013

Features

  • Support for Microsoft VS 2013, ASP.NET Web API 2, and Entity Framework 6. This release primarily involves 3 new dlls and 4 new Nuget packages that together support Web API 2 and Entity Framework 6. All older Breeze packages are also still supported.

    The Breeze JavaScript client (1.4.5) will work with both the new Web API 2 dlls as well as the old ones.

    New dlls

    • Breeze.ContextProvider
    • Breeze.ContextProvider.EF6
    • Breeze.WebApi2

    New Nuget packages

    • Breeze.Server.ContextProvider
      • Provider Breeze support for a backend independent storage model.
    • Breeze.Server.ContextProvider.EF6
      • Provider Breeze specific Entity Framework 6 support on top of the Breeze.Server.ContextProvider.
    • Breeze.Server.WebApi2
      • Provides Breeze support for ASP.NET Web API 2 independent of any specific backend storage model.
    • Breeze.WebApi2.EF6
      • Composite nuget that contains the Breeze client, Microsoft's Web API 2 support and all 3 Breeze assemblies shown above.

    To convert a (legacy) Breeze project to Breeze ASP.NET Web API 2 and Entity Framework 6 project involves

    1. uninstalling all (legacy) Breeze nuget packages - ( These will now all have the name "Legacy" in them).
    2. reinstalling new Breeze nuget packages - For single project solutions on Entity Framework this will mean just installing the one "Breeze.WebApi2.EF6" package.
    3. replacing the "Breeze.WebApi" and "Breeze.WebApi.EF" namespaces with "Breeze.WebApi2" , "Breeze.ContextProvider" and "Breeze.ContextProvider.EF6".

1.4.4Oct 14, 2013

Features

  • Added OData V3 support. Previously only OData V2 was supported.
  • Added EntityManager.acceptChanges and EntityManager.rejectChanges methods. These methods basically call EntityAspect.acceptChanges/rejectChanges for every changed entity within an EntityManager.
  • Added support for custom metadata.
  • Added an Angular Ajax adapter. The new adapter can be initialized by calling

        breeze.config.initializeAdapterInstance("ajax", "angular");  

    The default Breeze Ajax adapter is still jQuery. The new angular adapter should be used if you do not want to use jQuery at all within an Angular application.

    This adapter makes use of Angular's $http to perform any Ajax calls. By default, Breeze will create isolated $http and $rootScope instances for these calls in order to avoid Angular side effects. If you want to provide your own $http instance instead you can use the setHttp method on the adapter instance itself.

         var instance = breeze.config.initializeAdapterInstance("ajax", "angular");
         instance.setHttp($http);

    This addition also involved making a "minor" breaking change to the AJAX adapter requirements and base implementation so as to not depend on the jQuery.AJAX API. (see Breaking changes below)

  • Updated metadata documentation.

Breaking Change

  • The Ajax adapter api was changed to allow support for Ajax adapters that are not jQuery "like". This change should NOT affect any applications unless they subclassed the existing Ajax adapter or called into it directly. Applications that called methods on the EntityManager or the MetadataStore are NOT affected by this change.

    The change involved the config parameter of API's "Ajax" method.

        adapter.ajax(config);

    The change was to the success and error callback function properties of the config object. These used to be defined as follows ( following the jQuery API).

        config.success := function (data, textStatus, XHR);
        config.error := function (XHR, textStatus, errorThrown);  

    These two properties are now defined as

        config.success := function (httpResponse);
        config.error := function (httpResponse);

    where the httpResponse object consists of the following properties and methods.

        httpResponse.data – {string|Object} – The response body
        httpResponse.status – {number} – HTTP status code of the response.          
        httpResponse.getHeaders(headerName) - Header getter function - a null headerName will return all headers. 
        httpResponse.error - {Error | String} - an optional error object
        httpResponse.config - {Object} The configuration object that was used to generate the request.

    This change has also made it much easier to create a stub or mock Ajax adapter.

Bug fixes

  • Fixed a bug with ES5 props in knockout not always being wrapped properly.
  • Fixed bug where initializers declared on ComplexTypes were not firing.
  • Fixed a bug where asking for an inlinecount with the OData provider was returning the count as as a string instead of a number.
  • Fixed a bug with jsonResultsAdapter processing where certain nested structures were not being parsed properly.
  • Fixed a bug where an "named query" without an entityType mapping could cause the Breeze web api implementation to return an entire table if any filter referenced an invalid field name.

1.4.2Sept 11, 2013

Features

  • Added support for Breeze "initializer" inheritance when constructing instances of Breeze subclassed entities. Entity initializers are called in sequence starting from the basemost Entity class.
  • The Breeze WebApi response to any SaveChanges operation that has validation errors now returns a 403 status code, instead of a 200. This has no effect on any Breeze code but will be noticeable to anyone watching Breeze's network traffic.
  • Complex objects are now supported in the EntityQuery.withParameters method.

    • Client code

      var query = EntityQuery.from("SearchCustomers")
      .withParameters( { CompanyName: "A", ContactNames: ["B", "C"] , City: "Los Angeles"  } );
    • Server Code

      public class CustomerQBE {
        public String CompanyName { get; set; }
        public String[] ContactNames { get; set; }
        public String City { get; set; }
      }
      
      
      [HttpGet]
      public IQueryable<Customer> SearchCustomers([FromUri] CustomerQBE qbe) {
        var ok = qbe != null && qbe.CompanyName != null & qbe.ContactNames.Length > 0 && qbe.City.Length > 1;
        if (!ok) {
          throw new Exception("qbe error");
        }
        // do something interesting with qbe ...
      }
  • Support for NHibernate - (this is a BETA feature). A sample is available now.

  • The Breeze.WebApi dll has been broken up into multiple assemblies.

    • There are now 3 Server side .NET assemblies instead of one.
      • Breeze.WebApi.Core - database and persistence framework independent code.
      • Breeze.WebApi.EF - Entity Framework specific code. Dependent on Breeze.WebApi.Core.
      • Breeze.WebApi.NH - NHibernate specific code. Dependent of Breeze.WebApi.Core.
    • There are four new NuGet packages
      • Breeze.Client - client JavaScript libraries only.
      • Breeze.Server.WebApi.Core - Server side only .NET assemblies.
      • Breeze.Server.WebApi.EF = Breeze.Server.WebApi.Core + Entity Framework assemblies
      • Breeze.Server.WebApi.NH = Breeze.Server.WebApi.Core + NHibernate assemblies.
    • The preexisting Breeze.WebApi package has been recomposed.
      • Breeze.WebApi = Breeze.Client + Breeze.Server.WebApi.EF

Breaking Change

  • The breakup of the Breeze.WebApi dll into several assemblies means that for any Entity Framework dependent Breeze server side projects.

    • The new Breeze.WebApi.EF assembly will need to be added as a reference. If you were already using a Breeze NuGet package then the updated version of your package should do this this automatically.
    • The Breeze.WebApi.EF namespace will need to be added to any 'using' code blocks.

This means that if you were using Breeze with the Entity Framework

   using Breeze.WebApi;

must be replaced with

  using Breeze.WebApi;
  using Breeze.WebApi.EF;

Bug fixes

  • Fixed several IE8 related bugs including 'Out of stack space" issue and Breeze incorrectly attempting to call 'Object.defineProperty' when it is not implemented.
  • Fix bug with OData provider and unmapped properties.

Intro to SPA with RubyAug 30, 2013

  • We've replaced the Web API and Entity Framework used to power the backend of Code Camper Jumpstart with Ruby on Rails.

1.4.1Aug 13, 2013

Features

  • The EntityManager.importEntities instance method now returns an object containing the list of entities imported and any temporary key mappings that occurred as a result of the import. The static version of this method has not changed, it still creates and returns a new EntityManager containing the imported entities.
  • An additional 'parent' property was added to the arguments passed to the EntityAspect.propertyChanged event. The value of this property will be different from that of the 'entity' property when the property in question is part of a nested complex type structure.
  • The MetadataStore.importMetadata method can now process 'Breeze' native metadata imports where base classes may not be defined before their subclasses. i.e. order no longer matters.
  • The 'value' parameter in the Predicate constructor is now overloaded to optionally support an object with 'value', 'isLiteral' and 'dataType' properties. This change was made to support queries where Breeze's inference engine does not have sufficient information to correctly infer the 'dataType' of a query clause.
  • The Predicate.create method and the Predicate constructor have been extended so that both will now also accept a standard 'OData' query clause. OData clauses may also be combined with any standard query clauses. However, any EntityQuery containing an explicit OData clause will only be executable remotely, i.e. you cannot execute these queries locally.

    var query = breeze.EntityQuery.from("Employees")
        .where("EmployeeID add ReportsToEmployeeID gt 3");   
  • The Predicate.and and Predicate.or methods have been extended so that any arrays or parameters passed into these methods are automatically filtered to exclude null or undefined 'predicates'. This allow for simpler composition of complex query expressions.

    // works even if any or all of pred1, pred2 or pred3 is null or undefined. 
    var predicate = Predicate.and([pred1, pred2, pred3]);
    var query = breeze.EntityQuery.from("Employees").where(predicate);
  • EntityQuery with a "take(0)" method call is now supported and will return no entities. This idiom is useful in conjunction with the EntityQuery.inlineCount method.

    // returns just the count of employees
    var query = breeze.EntityQuery.from("Employees").take(0).inlineCount(true);
  • ES5 properties defined within an inheritance hierarchy via JavaScript's Object.defineProperty method are now fully supported in any custom constructors registered with Breeze. This support is currently limited to Angular (via the backingStore adapter) and Knockout. Backbone support for this feature is coming soon.

  • Typescript breeze.d.ts file updated for TypeScript 0.9.1

  • Several additional standard validators have been added including:

    • breeze.Validator.regularExpression
    • breeze.Validator.creditCard
    • breeze.Validator.emailAddress
    • breeze.Validator.phone ( BETA)
    • breeze.Validator.url

Use them as you would the other stock validators. Here's an example:

// Add Url validator to the blog property of a Person entity
// Assume em is a preexisting EntityManager.
var personType = em.metadataStore.getEntityType("Person"); //get the Person type
var websiteProperty = personType.getProperty("website"); //get the property definition to validate
websiteProperty.validators.push(Validator.url()); // push a new validator instance onto that property's validators

With the breeze.Validator.makeRegExpValidator static helper, you can quickly mint new validators that encapsulate a regular expression. For example, we can create a U.S. zipcode validator and apply it to one of the Customer properties.

// Make a zipcode validator
function zipValidator = breeze.Validator.makeRegExpValidator(
    "zipVal",  
    /^\d{5}([\-]\d{4})?$/,  
    "The %displayName% '%value%' is not a valid U.S. zipcode");

// Register it with the breeze Validator class.
breeze.Validator.register(zipValidator);

// Add it to the Customer.PostalCode data property. Assume em is a preexisting EntityManager.
var custType = em.metadataStore.getEntityType("Customer");  //get the Customer type
var zipProperty = custType.getProperty("PostalCode");    //get the PostalCode property definition
zipProperty.validators.push(zipValidator);    // get that property's validators and push on the zipValidator

See the API docs for more information on how to use these new validators.

Many of these new validators correlate to .NET data annotations. In a future release, the Breeze.NET EFContextProviderwill be able to include these validations in the metadata automatically for you. For now, you'll have to add them to the properties on the client side as shown above.

Bug fixes

  • Fixed bug with EntityQuery.inlineCount when used in conjunction with a orderBy clause involving a nested property path.
  • Fixed bug with empty EntityQuery.orderBy, select and expand clauses throwing an exception, instead of simply removing the clause from the resultant EntityQuery.
  • Fixed bug where EntityManager.importEntities did not always fixup relationships completely in complex graphs
  • Fixed bug to insure that EntityManager.exportEntities and importEntities preserves null values.

Zza! sampleAugust 05, 2013

  • 100% JS sample, written for Node.js running Express with a MongoDB database.

1.4.0July 23, 2013

Features

Client side

Server side (Node.js)

Server side (.NET)

  • New server-side interception point, AfterSaveEntities.

  • New options for server-side transaction control. SaveChanges now has an optional TransactionSettings parameter, which controls the type of transaction that wraps the BeforeSaveEntites, SaveChangesCore, and AfterSaveEntities methods.

  • New methods on ContextProvider for use in BeforeSaveEntities and AfterSaveEntities. These methods help allow re-use of database connections, which reduces the need for distributed transactions.

  • Save validation enhancements. (Communicate server side validation errors to the client.)

  • Server side validation errors can be returned in using .NET Validation Attributes or by throwing an EntityErrorsException within the server side BeforeSaveEntities delegate or virtual method.

Bugs

  • Fixed: Bug where inlineCount was null/undefined when query results were sorted by a nested property path.
  • Fixed: Remaining validators were not being called after the first validator failed.
  • Fixed: Server side implementation using FirstOrDefault would causing the query to fail when a null was returned.
  • Fixed: EntityManager.getEntityByKey was failing with some inheritance models.
  • Fixed: Breeze was not applying extended query semantics to Web API methods typed to return an HttpResponseMessage. The fix involves the requirement that to apply the query properly to these methods they must have a [BreezeQueryable] attribute applied directly to them. This is not required for methods that return an IQueryable directly.
  • Fixed: EntityManager.exportMetadata would fail with the JSON2.stringify ES5 shim.
  • Fixed: EntityManager.executeQueryLocally could incorrectly interpret some queries involving strings starting with the letter "P" as being queries for "duration" properties.

Breaking changes

  • entityAspect.removeValidationErrors has changed

    old signature: removeValidationErrors(validator, property)

    new signature removeValidationErros(validationErrorOrKey)

    If you don’t have a ValidationError you can obtain a key via ValidationError.getKey(validator, property); If you do have a ValidationError, it now has a publicly avail ‘key’ property that can be used to remove it manually if necessary.

  • The description of client side validation errors caught during a save before posting to the server has changed.

    Client side validation errors caught during a save, but before posting to the server, cause the save to fail and be routed to the fail promise. The fail promise returns an error object that contains a description of the errors. This description has changed.

    Previously this error object contained an entitiesWithErrors property that contained a list of all of the entities that had failed validation. This property has now been replaced with the entityErrors property. The entityErrors property returns a collection of entityError objects as described above.

    This change was made in order to retain consistency between save failures that occurred on the server and those that failed before posting to the server on the client.

  • The ContextProvider base class has been changed - 3 new abstract methods were added and one method signature was changed. This change will ONLY affect developers who directly subclassed the ContextProvider base class. The EFContextProvider experienced no breaking changes.

    • New methods
    • Changed method