Extending entities on a per view basis with breeze.js in SPA - breeze

Trying to figure out how to extend entities that I query from breeze.js on a per-view basis in a single page application. Right now breeze is acting as the gate-keeper when it comes to extending (a.k.a materializing) them and I’m wondering what other options are available to allow me to do this. I initially started with knockout’s mapping plugin but found that it refused to handle child collections for some reason so I moved to using breeze’s constructor function and initializer methodology. The problem with this is that you can only define one custom "model" for an entity. I am looking for approaches that would allow a custom "model" of an entity on a per-view basis. I’ve already ruled out multiple managers. Querying meta-data multiple times is a huge unnecessary hit just to get this working.
This diagram visualizes what I’m trying to achieve. Both View 1 and View 2 ultimately query Entity B and both views require their own specific customization of the "model" of Entity B. Since View 1 loads first it’s custom "model" of Entity B "wins" and View 2 doesn’t have the opportunity to customize it. When View 2 eventually runs it’s query, any entities of type B that were already loaded by View 1 will have the custom "model" that View 1 defined which will make View 2 explode during binding. Any entities not already loaded by View 1 will now have View 2's custom "model" which would eventually crash View 1 if it could even get that far down the road. See this post.
My thought was to manually create my own custom "model" for each view that has an Entity observable and I could then iterate over every entity returned from a breeze query and new up this custom "model" and pass in the current item, assigning it to the Entity property. I don't really want to do this because I now have I'll have tons of iteration code everywhere and I'd much rather use knockout's mapping plugin. Pseudo code:
function view1EntityBModel(entity) {
var self = this;
self.Entity = ko.observable(entity);
self.myCustomProperty = ko.observable();
...
}
function view2EntityBModel(entity) {
var self = this;
self.Entity = ko.observable(entity);
self.isExpanded = ko.observable(false);
...
}
I was wondering if there are any other solutions available to achieve this same goal?
Or even better does anyone know how to make the knockout mapping plugin working on child collections?
I think the problem here is that by the time the mapping plugin gets a-hold of the breeze data the Children collection has already been converted into an observable array and the mapping plugin doesn't know that it needs to "call" the Children() property in order to get back a list.
var categoryMapper = {
create: function (options) {
return new categoryModel(options.data);
},
Children: { // this doesn't fire for the children
create: function (options) {
return new categoryModel(options.data);
}
}
}
function categoryModel(data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
}

Guessing that you've moved on by now, but thought I'd offer a recommendation for others in a similar position.
Our solution to a similar situation borrows from the breeze.js TempHire sample solution which implements a client side repository/uow pattern. The solution uses an EntityMananagerProvider to manage multiple EntityManagers. The EntityMananagerProvider makes a single call for metadata, which is then used to create new child EntityManagers - satisfying your concern regarding multiple metadata calls. You can then use custom models/uow/repositories to extend the child manager for specific views.

Related

use ToListAsync() with navigation property

I am using ASP.NET MVC with Entity Framework.
I have an entity called "AllUserData".
I have a second entity called "Genres". Each row in the table is a genre.
These two entities have a one-to-many relationship. So in the class definition of the "AllUserData" class, I have
public virtual ICollection PreferredGenres { get; set; }
I am able to successfully read the genres preferred by each user using
AllUserData aud = db.AllUserData.Single(b => b.UserId == currentUserId);
var chosengenres = aud.PreferredGenres.ToList()
However I cannot use
AllUserData aud = db.AllUserData.Single(b => b.UserId == currentUserId);
var chosengenres = await aud.PreferredGenres.ToListAsync()
Visual Studio says "ICollection does not contain a definition for 'ToListAsync' and the best extension method overload 'QueryableExtensions.ToListAsync(IQueryable)' requires a receiver of type 'IQueryable'.
Why is this happening? The only difference between the two was that in one case I used ToList() and in the other I used ToListAsync().
Can async methods not be used with navigation properties? In a real life application there are many cases where there are relationships between various entities; can asynchronous methods not be used when accessing properties using these relationships? Is there some way around this? I'd rather do things asynchronously if possible.
Your navigation property would have been declared as an ICollection, standard for Entity properties -- the compiler won't be pleased.
However, you can get an IQueryable with AsQueryable or with another Select() (if that makes sense for your needs) between the navigation collection and the ToListAsync().
ToList() can operate on IEnumerable (which includes ICollection and IQueryable). ToListAsync() has only been made to work with IQueryable, hence the message from VS. The "why" may lie in the implementation details.
Ok, it seems entity framework doesn't allow for calling the navigation property asynchronously in this manner.
What worked for me is earger loading the navigation property in the beginning. (Thanks to user daf for sending me in the correct direction).
So instead of
AllUserData aud = await db.AllUserData.SingleAsync(b => b.UserId == currentUserId);
var usergenres = await aud.PreferredGenres.ToListAsync();
which does not work, I can instead do this :
AllUserData aud = await db.AllUserData.Include(p=>p.PreferredGenres).SingleAsync(b => b.UserId == currentUserId);
var usergenres = aud.PreferredGenres.ToList();
This way the first query asks to pull all necessary information from the database through eager loading with .Include(), and does so asynchronously due to the user of .SingleAsync(). The next statement uses .ToList(), but shouldn't make a second trip to the database since the data is already eager loaded, so it doesn't matter that it is async. The whole operation is now async.
I also realized this same question has been asked previously on StackOverflow; it is a little difficult to find depending on what search terms you used: Entity Framework Designer First get navigation property as Tasks. The selected answer provides 4 different solutions, out of which the first one is similar to what I am using now.
It also appears possible to designate navigation properties as async when defining the entity class- see the section titled "Async Lazy Loading" on this page: here The sample snippet demonstrates how to do this for a single navigation property; I don't know if it can be done for an ICollection navigation property as well, which is what I need, but I didn't do any further digging either.

How to move from untyped DataSets to POCO\LINQ2SQL in legacy application

Good day!
I've a legacy application where data access layer consists of classes where queries are done using SqlConnection/SqlCommand and results are passed to upper layers wrapped in untyped DataSets/DataTable.
Now I'm working on integrating this application into newer one where written in ASP.NET MVC 2 where LINQ2SQL is used for data access. I don't want to rewrite fancy logic of generating complex queries that are passed to SqlConnection/SqlCommand in LINQ2SQL (and don't have permission to do this), but I'd like to have result of these queries as strong-typed objects collection instead of untyped DataSets/DataTable.
The basic idea is to wrap old data access code in a nice-looking from ASP.NET MVC "Model".
What is the fast\easy way of doing this?
Additionally to the answer below here is a nice solution based on AutoMapper: http://elegantcode.com/2009/10/16/mapping-from-idatareaderidatarecord-with-automapper/
An approach that you could take is using the DataReader and transfer. So for every object you want to work with define the class in a data transfer object folder (or however your project is structured) then in you data access layer have something along the lines of the below.
We used something very similar to this in a project with a highly normalized database but in the code we did not need that normalization so we used procedures to put the data into more usable objects. If you need to be able to save these objects as well you will need handle translating the objects into database commands.
What is the fast\easy way of doing
this?
Depending on the number of classes etc this is could not be the fastest approach but it will allow you to use the objects very similarly to the Linq objects and depending on the type of collections used (IList, IEnumerable etc) you will be able to use the extension methods on those types of collections.
public IList<NewClass> LoadNewClasses(string abc)
{
List<NewClass> newClasses = new List<NewClass>();
using (DbCommand command = /* Get the command */)
{
// Add parameters
command.Parameters["#Abc"].Value = abc;
// Could also put the DataReader in a using block
IDataReader reader = /* Get Data Reader*/;
while (reader.Read())
{
NewClass newClass = new NewClass();
newClass.Id = (byte)reader["Id"];
newClass.Name = (string)reader["Name"];
newClasses.Add(newClass);
}
reader.Close();
}
return newClasses;
}

Entity Framework 4 Code First and the new() Operator

I have a rather deep hierarchy of objects that I'm trying to persist with Entity Framework 4, POCO, PI (Persistence Ignorance) and Code First. Suddenly things started working pretty well when it dawned on me to not use the new() operator. As originally written, the objects frequently use new() to create child objects.
Instead I'm using my take on the Repository Pattern to create all child objects as needed. For example, given:
class Adam
{
List<Child> children;
void AddChildGivenInput(string input) { children.Add(new Child(...)); }
}
class Child
{
List<GrandChild> grandchildren;
void AddGrandChildGivenInput(string input) { grandchildren.Add(new GrandChild(...)); }
}
class GrandChild
{
}
("GivenInput" implies some processing not shown here)
I define an AdamRepository like:
class AdamRepository
{
Adam Add()
{
return objectContext.Create<Adam>();
}
Child AddChildGivenInput(Adam adam, string input)
{
return adam.children.Add(new Child(...));
}
GrandChild AddGrandchildGivenInput(Child child, string input)
{
return child.grandchildren.Add(new GrandChild(...));
}
}
Now, this works well enough. However, I'm no longer "ignorant" of my persistence mechanism as I have abandoned the new() operator.
Additionally, I'm at risk of an anemic domain model since so much logic ends up in the repository rather than in the domain objects.
After much adieu, a question:
Or rather several questions...
Is this pattern required to work with EF 4 Code First?
Is there a way to retain use of new() and still work with EF 4 / POCO / Code First?
Is there another pattern that would leave logic in the domain object and still work with EF 4 / POCO / Code First?
Will this restriction be lifted in later versions of Code First support?
Sometimes trying to go the POCO /
Persistence Ignorance route feels like
swimming upstream, other times it feels
like swimming up Niagra Falls. Still, I want to believe...
Here are a couple of points that might help answer your question:
In your classes you have a field for the children collection and a method to add to the children. EF in general (not just Code First) currently requires that collections are surface as properties, so this pattern is not currently supported. More flexibility in how we interact with classes is a common ask for EF and our team is looking at how we can support this at the moment
You mentioned that you need to explicitly register entities with the context, this isn’t necessarily the case. In the following example if GetAdam() returned a Adam object that is attached to the underlying context then the new child Cain would be automatically discovered by EF when you save and inserted into the database.
var adam = myAdamRepository.GetAdam();
var cain = new Child();
adam.Children.Add(cain);
~Rowan

Code re-use with Linq-to-Sql - Creating 'generic' look-up tables

I'm working on an application at the moment in ASP.NET MVC which has a number of look-up tables, all of the form
LookUp {
Id
Text
}
As you can see, this just maps the Id to a textual value. These are used for things such as Colours. I now have a number of these, currently 6 and probably soon to be more.
I'm trying to put together an API that can be used via AJAX to allow the user to add/list/remove values from these lookup tables, so for example I could have something like:
http://example.com/Attributes/Colours/[List/Add/Delete]
My current problem is that clearly, regardless of which lookup table I'm using, everything else happens exactly the same. So really there should be no repetition of code whatsoever.
I currently have a custom route which points to an 'AttributeController', which figures out the attribute/look-up table in question based upon the URL (ie http://example.com/Attributes/Colours/List would want the 'Colours' table). I pass the attribute (Colours - a string) and the operation (List/Add/Delete), as well as any other parameters required (say "Red" if I want to add red to the list) back to my repository where the actual work is performed.
Things start getting messy here, as at the moment I've resorted to doing a switch/case on the attribute string, which can then grab the Linq-to-Sql entity corresponding to the particular lookup table. I find this pretty dirty though as I find myself having to write the same operations on each of the look-up entities, ugh!
What I'd really like to do is have some sort of mapping, which I could simply pass in the attribute name and get out some form of generic lookup object, which I could perform the desired operations on without having to care about type.
Is there some way to do this to my Linq-To-Sql entities? I've tried making them implement a basic interface (IAttribute), which simply specifies the Id/Text properties, however doing things like this fails:
System.Data.Linq.Table<IAttribute> table = GetAttribute("Colours");
As I cannot convert System.Data.Linq.Table<Colour> to System.Data.Linq.Table<IAttribute>.
Is there a way to make these look-up tables 'generic'?
Apologies that this is a bit of a brain-dump. There's surely imformation missing here, so just let me know if you'd like any further details. Cheers!
You have 2 options.
Use Expression Trees to dynamically create your lambda expression
Use Dynamic LINQ as detailed on Scott Gu's blog
I've looked at both options and have successfully implemented Expression Trees as my preferred approach.
Here's an example function that i created: (NOT TESTED)
private static bool ValueExists<T>(String Value) where T : class
{
ParameterExpression pe = Expression.Parameter(typeof(T), "p");
Expression value = Expression.Equal(Expression.Property(pe, "ColumnName"), Expression.Constant(Value));
Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(value, pe);
return MyDataContext.GetTable<T>().Where(predicate).Count() > 0;
}
Instead of using a switch statement, you can use a lookup dictionary. This is psuedocode-ish, but this is one way to get your table in question. You'll have to manually maintain the dictionary, but it should be much easier than a switch.
It looks like the DataContext.GetTable() method could be the answer to your problem. You can get a table if you know the type of the linq entity that you want to operate upon.
Dictionary<string, Type> lookupDict = new Dictionary<string, Type>
{
"Colour", typeof(MatchingLinqEntity)
...
}
Type entityType = lookupDict[AttributeFromRouteValue];
YourDataContext db = new YourDataContext();
var entityTable = db.GetTable(entityType);
var entity = entityTable.Single(x => x.Id == IdFromRouteValue);
// or whatever operations you need
db.SubmitChanges()
The Suteki Shop project has some very slick work in it. You could look into their implementation of IRepository<T> and IRepositoryResolver for a generic repository pattern. This really works well with an IoC container, but you could create them manually with reflection if the performance is acceptable. I'd use this route if you have or can add an IoC container to the project. You need to make sure your IoC container supports open generics if you go this route, but I'm pretty sure all the major players do.

How can I use nHibernate to get a small subset of object properties for list view

I am using ASP.NET-MVC and nHibernate for the first time. Great tools, but big learning curve!
I have a list view of objects that are quite large (each has about 60 properties). In the list view I am only using about 10 of these properties. Performance is not too bad, but it seems a waste to fully hydrate these objects. What is the recommended practice?
I tried using HQL to select fewer properties, but it seems like it won't partially hydrate an object. I also tried making property on the main object that was a header class with the list view properties, but I couldn't seem to get it mapped properly. I think this should be easy but I've really been struggling with it.
EDIT:
I kept coming back to this because I knew Anton had given me the answer and I just couldn't see it.
There are three things you need to do:
Make an object with the properties you want.
Make a mapping file to import this object.
<hibernate-mapping
xmlns="urn:nhibernate-mapping-2.2"
namespace="Core.Entities"
assembly="Core"
default-access="property">
<import class="RequestHeader" />
</hibernate-mapping>
If you are using HQL, your object must contain a constructor with all the properties, in the same order, as your select new statement. If you use the Criteria API, you don't need to do this.
public IList<RequestHeader> ListAll()
{
using (ISession session = GetSession())
{
using (ITransaction tx = session.BeginTransaction())
{
IList<RequestHeader> results = session.CreateCriteria(typeof (Request), "r")
.CreateCriteria("Requestor", "req", JoinType.InnerJoin)
.CreateCriteria("r.Grant", "g", JoinType.InnerJoin)
.SetProjection(Projections.ProjectionList()
.Add(Projections.Property("r.Id"), "Id")
.Add(Projections.Property("r.Status"), "Status")
.Add(Projections.Property("r.SubmissionDate"), "SubmissionDate")
.Add(Projections.Property("req.Name"), "Requestor")
.Add(Projections.Property("g.Number"), "Number"))
.SetResultTransformer(Transformers.AliasToBean(typeof (RequestHeader)))
.SetMaxResults(10000)
.List<RequestHeader>();
tx.Commit();
return results;
}
}
}
60 properties is too much. See Component mapping.
As for selecting a subset of properties, see this: you need a select new HQL construct. Be aware, though, that you need an appropriate constructor and that an object you'll get cannot be saved back to the DB.

Resources