Tangster
Tangster

Reputation: 33

How can I do this LINQ query in BreezeJS?

I'm swapping a project into BreezeJS and having trouble getting this query right. I have a query I was using in LINQ that was doing it perfectly. It is:

                var transactionTypes = from tpt in db.TransactionPropertyTypes
                            from et in tpt.TransactionTypes
                            where tt.TransactionTypeName == transactionType.TransactionTypeName
                            select tpt;

Where transactionType is an object I've passed in. My model matches up perfectly. Basically there are three tables. TransactionPropertyTypes, TransactionTypes and a one linking the foreign keys together. Any help is greatly appreciated!

So far my best shot in breeze is:

            breeze.EntityQuery.from("TransactionPropertyTypes")
            .from("TransactionTypes")
                .where("TransactionType.TransactionTypeName", "==", type)                
                .using(man).execute()

The error the console prints is: Error: The left hand side of a binary predicate cannot be a literal expression, it must be a valid property or functional predicate expression: TransactionType.TransactionTypeName

Any help is appreciated!

Upvotes: 0

Views: 1298

Answers (2)

Paul Harker
Paul Harker

Reputation: 21

Create a Predicate Object

Breeze allows for complex predicates to be created and built upon:

var Predicate = breeze.Predicate;

var mypred = Predicate.Create("TransactionType.TransactionTypeName", "==", valueToFind);

// If more clauses, add them like this
if (2ndValueToFind) {
    mypred = mypred.and(Predicate.create('AnotherField', '==', 2ndValueToFind));
}
        breeze.EntityQuery.from("TransactionPropertyTypes")
        .from("TransactionTypes")
            .where(mypred)                
            .using(man).execute()

I don't believe this will solve the many-to-many problem, but it is very useful.

Upvotes: 0

Ward
Ward

Reputation: 17863

Only one 'from' clause

Steve's solution won't work because you can't have double "from" clauses.

Let me restate in English what I think you're intentions are.

Give me all instances of TransactionPropertyType that have a particular TransactionType among their TransactionTypes.

I will assume that your TransactionPropertyType has a collection navigation property of transactionTypes.

If I've guessed correctly, you're looking for an "any" query.

Something like this should work:

query = EntityQuery.from('TransactionPropertyTypes')
                   .where('transactionTypes', 'any',
                      'name', 'eq', desiredTransType.name);

Many to many

Upon re-reading I see that TransactionPropertyType and TransactionType are related many-to-many. Breeze doesn't support many-to-many relationships yet.

But you also said that you can surface the mapping table that implements the relationship as an entity.

You didn't name it; I'll call it the TransPropTransTypeMap. I'll assume that there is a through navigation path that goes TransactionPropertyType.transPropTransTypeMaps.transactionType.

The re-written query becomes:

query = EntityQuery.from('TransactionPropertyTypes')
                   .where('transPropTransTypeMaps', 'any',
                      'transactionType.name', 'eq', desiredTransType.name);

I just added an ngDocCode:query_with_predicates test that does the same kind of thing for the Northwind m-to-m relationship, 'Order-OrderDetail-Product', in which OrderDetail plays the role of the mapping entity.

it("an ANY predicate through a many-to-many mapping table", function (done) {

    // Get first Order with an OrderDetail that has a product named 'Chai'
    // OrderDetail is the mapping table in this scenario:
    //     Order <-(1,M)-> OrderDetail <-(M,1)-> Product

    var pred = new Predicate('OrderDetails', 'any', 
                             'Product.ProductName', 'eq', 'Chai');

    EntityQuery.from('Orders')
        .where(pred)
        .top(1)
        .expand('OrderDetails.Product')
        .using(em).execute().then(success).then(done, done);

    function success(data){
        var order = data.results[0] || {};
        var hasChai = order.OrderDetails.some(function(od){
            return od.Product.ProductName ===  'Chai';
        });
        expect(hasChai).to.be.true;
    }
});

Upvotes: 2

Related Questions