Breeze Batch Saves for some entities - breeze

We use the Abstract Dataservice REST Adapter in Breeze, but are interested in batching saves for some entities. We depend on synchronous saves, so we want certain entities to be posted down together. Is this something we need to write custom adapter code to accomplish, or is there any options that Breeze has available out of the box? Any insight on similar patterns would be greatly appreciated!

I don't think a custom adapter would be necessary, it sounds like you might be able to use EntityManager.getChanges, specifying the entity type:
var custType = em.metadataStore.getEntityType("Customer");
var changedCustomers = em.getChanges(custType);
em.saveChanges(changedCustomers);
You will want to update the code to reflect your business rules, but you should find getChanges helpful.

Related

BreezeJs with standard REST and Json Patch

we currently have a project where we will use a standard RESTful Interface implemented in WebApi. So there will not be a single Breeze-Controller with a single SaveChanges method to handle all CUD request. Instead, there will be a Controller by type Web Api implementation where the CRUD Actions will be handled by each Controller. Additionally, we think of using JSON Patch to just send the needed data to the backend.
Is there any Adapter already implemented for BreezeJs? There is a abstractrest implementation in breeze labs which sounds like the right base class. But this should be something other already encountered. Is there an example or implementation we could use for our needs?
Thank you for your help!
Marc
You are far from the only person who could benefit from such an adapter. I've been meaning to write about this topic for ... well I think it is years now. It's strange that not enough people have asked to push me over the hump.
You're on the right path with the AbstractRestDataServiceAdapter in Breeze Labs.
I recently wrote a derived adapter to do pretty much what you have in mind ... although I was targeting the Web API (aka MVC6) in ASP.NET 5. Take a look at this "mvc6-unicorn" adapter for inspiration.
It uses POST for modified entities but you could use PATCH or MERGE as in this fragment from the "OData" adapter in b00_breeze.dataService.odata.js.
else if (aspect.entityState.isModified()) {
...
request.method = "MERGE";
request.data = helper.unwrapChangedValues(entity, entityManager.metadataStore, transformValue);
} ...
Please note also that the client-side interpretation of the JSON data within the JsonResultsAdapter is greatly facilitated by a small amount of server-side Json.NET reconfiguration along the lines of what you see in this ApiConfiguration class here (that's the MVC6 equivalent to WebApiConfig).
Sadly, I have to leave you here with only these clues to craft a solution that works for you.
The full story ... which I do hope to write "soon" ... belongs in our Breeze documentation.
Please feel free to return if you get stuck on specific points.

What benefit do I get when I use Breeze JS with MS MVC pattern?

I need some help in understanding the benefit of using Breeze JS in a Visual Studio MVC project.
With MVC, using razor, I can bind my model properties to controls on the page and have any changes user makes sent back to the server without me writing any code. So, I am not really understanding if in this situation use of Breeze can be beneficial.
Certainly, I am not looking at the whole picture. And that is the reason I am asking this question here. Can anyone explain.
TIA.
kr
breeze is very helpful when you use ORM like NH\EF (also good for nosql and mongo)
if you do stuff like TPT\TPH and circular ref data it's hard to serialize by yourself
breeze takes care of that part for you
you can get your entities on the client side and keep change tracking
also no need to write sql\sp\functions to query data you can do all that on the client side
breeze supports client side cache with ease
breeze also works great with angularjs and knockout, if you bind data to the scope and then use breeze manager to delete or add more data no need to push or splice it breeze does that for you
breeze can do so much more so please check out the docs and features and find out what breeze can do for your project
I am using MVC Pattern and breeze will help us to integrate our typeScript interface generated from T4Ts taking the advantage of have strongly typed entities.
export interface Library extends breeze.Entity {
Category: string;
Name: string;
}
var manager = new breeze.EntityManager('api/library');
var query = new breeze.EntityQuery()
.from("Library");
manager.executeQuery(query).then(data => {
var employees = <Library []>data.results;
}).fail(e => {
alert(e);
});

Breeze Creating Complex Entities with Lookup Tables

I am new to Angular and Breeze. I am trying to create a new group with customer relationships at the same time. My DB structure has 3 tables that are affected the Groups, UserToGroups and the CustomersToGroups tables. The entity manager has the tables and references registered. My question is, do I need to first create the group before I can add the records to the lookup tables? If a groupId does not exist it should not be able to create a UserToGroups record or a CustomersToGroups record. Is Breeze and the entity manager handling all of this? Can I do this all in one shot? How?
controller.js
function addCustAndGroup(CustId, grpId, GroupCategory, GroupDesc) {
var newGroup = app.dataservice.manager.createEntity("Group");
newGroup.GroupId(CustId);
newGroup.GroupCategory(GroupCategory);
newGroup.GroupDescription(GroupDesc);
manager.StudnetsToGroup.push(studentToGroup);
manager.UserToGroup.push(userToGroup);
manager.saveChanges();
};
I want to point out something that you're doing that I find worrisome: your dataservice exposes the manager to its caller. A key reason for having a dataservice is to encapsulate the EntityManager ... to hide it from all callers. If you're going to expose the manager to callers, why bother with the dataservice at all?
I don't have a lot of absolute rules but you've broken one of the few, namely "never expose the EntityManager from the dataservice." I have never had to relax that rule. I promise you that you will regret breaking it.
I think what you want to do is have your dataservice expose a createGroup method. All of the work of creating the group should be tucked inside the dataservice.
Now that I'm done ranting, I'm trying to make sense of your actual question and your code. I'm sorry but I'm kind of lost. I'm stumped by manager.UserToGroup.push because (a) the EntityManager doesn't have a UserToGroup member and (b) there is no push method in the Breeze API ... certainly nothing like that for adding/attaching entities to the EntityManager cache.
I don't know which of your "tables" are "lookup tables". I'm kind of confused by the words "table" and "record" anyway as you seem really to be talking about entity type and entity instances, not database objects. I get the parallelism but it's worth maintaining a clear distinction between entities and the database structures to which they are mapped.
A final confession of my confusion: your question subject refers to "Complex Entities". Breeze has a notion called "Complex Type". I don't think that's what you mean. I think you mean that you believe your Entity is complicated. Is that right?
I sense that none of this is getting closer to an answer to your question ... which I cannot quite fathom. It seems to be about whether you have to create one type of entity before a different type. But I can't be sure.
I think you'll have to clarify your question before you get a proper answer.

How to use Breeze with multiple Entity Framework Contexts

Is it possible or practical to get a single Breeze controller to work with multiple EF contexts? Each context has a different data model.
Or, is it possible to have a single Breeze client use two different Breeze controllers?
Both are possible. Both are common.
Usually you would have one-EF-Context-per-controller. That is certainly the easy path (but not the only possible path!).
On the client, you could treat these as distinct "data services". Something like the following in the two-context case:
// Highly condensed, simplified example
var fooServiceName = 'api/foo';
var barServiceName = 'api/bar';
var fooManager = new breeze.EntityManager(fooServiceName);
var barManager = new breeze.EntityManager(barServiceName);
// use each manager in its own workflow
My assumption is that you have separate models because you have separate workflows. That assumption usually holds and is certainly the easiest way to proceed.
I then would structure my client application as separate client-side modules, each with its own EntityManager.
I won't speculate further; let us know if this suits your purpose or if you have some other need in mind.
As an aside, I would rather the controllers themselves not know about EF contexts at all. I'd like to see them isolated in supporting external classes for easier testing. But, regarding the essence of your question, you should be fine.

Advice on POCO Validation with ASP.NET MVC/Entity Framework

Here's the scenario:
ASP.NET MVC2 Web Application
Entity Framework 4 (Pure POCO's, Custom Data Context)
Repository Pattern
Unit of Work Pattern
Dependency Injection
Service Layer mediating Controller -> Repository
So basically, all the cool stuff. :)
Flow of events for a basic UI operation ("Adding a Post"):
Controller calls Add(Post) method on service layer
Service layer calls Add(T) on repository
Repository calls AddObject(T) on custom data context
Controller calls Commit() on Unit of Work
Now, i'm trying to work out where i can put my validation.
At this stage, i need two types of validation:
Simple, independant POCO validation such as "post must have a title". This seems a natural fit for Data Annotations on the POCO's.
Complex business validation, such as "cannot add a comment to a locked post". This can't be done by Data Annotations.
Now, i have been reading "Programming Entity Framework, Second Edition" by Julie Lerman (which is excellent BTW), and have been looking into hooking into the SavingChanges event in order to perform "last-minute" validation. This would be a nice way to ensure validation always happens whenever i do "something" (add, modify, delete), but it's also a little late IMO (as the items are already in the state manager) - so what can i do if validation fails, remove them?
I could of course make my POCO's implement an interface (say "IValidatable"), and call a method on this interface during this event.
But this seems "too late" for business validation - is this the consensus?
I'm basically looking for guidance here, i'm trying to design a re-usable, intelligent validation scheme for complex business logic, given my above architecture.
Another curve-ball for you - as you know, POCO's with EF mean the POCO's have all the properties on the DB - so i might have a "PostID" property, with get/set accessors (as EF needs to get/set these properties).
But the problem is, "PostID" is an identity column, so how do i protect the field from being explicity set? E.g if i (for some reason) do the following:
var post = service.FindSingle(10);
post.PostId = 10;
unitOfWork.Commit();
This will throw a SqlException. How can i prevent this? I can't "hide" the property (make it private, or even internal) as the POCO's are in a seperate assembly to the Repository.
A note on validation - i'm planning to create custom exceptions (deriving from Exception). So when validation fails, i need to throw these exceptions.
That way, i can code something like this on my controller:
[HttpPost]
public ActionResult AddPost(Post post)
{
try
{
IUnitOfWork uow = new UnitOfWork();
postService.Add(post);
uow.Commit();
}
catch(InvalidPostOperation ipo)
{
// add error to viewmodel
}
}
Will i have to manually do validation on the service layer everytime i do an Add? Then how can i handle Save? (as this is on the Unit of Work, not the service layer).
So to prevent this from being a "all over the place" question, here are my questions:
Simple POCO validation - should this be done with Data Annotations? Pros/cons/gotchas?
Under what circumstances (if any) should we be hooking into the SavingChanges event of the EF Data Context in order to provide validation?
Where should i be performing complex business validation? In the service explicity, or a method on the POCO's (which i can call from service). How can i create an intelligent/reusable scheme?
How can we "hide" auto-generated properties of POCO's from being tampering with?
Any thoughts would be most appreciated.
Apologize if this post is "too long", but it's an important issue and one that can be solved in many ways, so i wanted to provide all the info in order for the best possible answer.
Thanks.
EDIT
The below answer is helpful, but i'm still (ideally) looking for more thoughts. Anyone else?
Well like you said, DataAnnotations is not appropriate for all situations. Cons are mainly complex validation (multiple property and multiple property different object) in my experience.
If i were you, i would leave business/domain validation out of the Data Layer (EF) as much as possible. If there is a Data Layer validation scenario, then fine (eg. validating complex parent/child relationships - this is purely DB stuff).
Yes, the complex business validation should be in the Service Layer or in the Model Objects (attached, via partial classes or some inheritance approach: interfaces/derived classes). There's debate about this between ActiveRecord people, Repository Pattern people and DDD people, but go with what works for you, is simple and will enable rapid deployment and low cost application maintenance. This is a simple example of how you might attach more complex validation to domain objects yet is still compatible with the DataAnnotations interface and thus is 'MVC friendly'.
Good question. -one i have not found a solution i'm 100% happy with yet. I have played with the idea of private setters and it's not great. Have a quick read of this summarized Evans DDD book. It's great quick read and it might provide some insight about the purpose and difference between Model Objects and Value Objects. This is where i think object design will mitigate the problems your having with the property "tampering" (as you call it) but without fixing the property visibility. Ie, another solution might lie elsewhere. Hope this helps.
Hey, probably a bit late but here goes anyway...
It all depends on your architecture, i.e. Is there a logical seperation, in your application: UI, Service Layer, Repository Layer. If you are hooking onto the Save event, how exactly will that be done? From what I observed you would be calling the repository Layer for Persistance only right? However you are hooking onto the save event, giving control back to the Service Layer/ Business Layer whatever then forcing the save through right?
I personally feel the Service layer/ Business Layer should take care of it in completion then say, hey mr repo layer -> save this object.
With regards to validation, Data Annotations should be used with the UI, so simple valiation like [Required] etc, this will be helpful with the Client Side validation but complex business logic or complex validation should be hooked into the service layer/ business layer, that way it is reusable across all entities/ objects/ POCOS etc.
With regards to preventing certain private fields not being tampered with... only allow your service layer/ business layer to actually set the object that will be persisted (yes i mean :) ...) hand coding it, I felt this was the safest option for me anyway, as I will simple do:
var updatedpost = _repo.GetPost(post.postid);
updatedpost.comment = post.comment;
updatedpost.timestamp = datetime.now;
Kind of wasteful but that way your buseinss layer takes control, however this is just my experience I may be wrong, I have read a lot into model binding, validaiton and other stuff however there seemed to be cases where things never work as expected e.g. [Required] attribute (see Brad WIlson's) post.

Resources