Spatial Join in Entity Framework - sql

I want to write a join statement in LINQ using the dbgeography's "Intersects" method (I am using EF June 2011 CTP). The problem is if I write something like this:
var joinQuery = from spQ in spatialTableQuery
join mnQ in MainQuery
on spQ.Polygon.Intersects(mnQ.PointGeography) equals 1
I get the following error:
The name 'mnQ' is not in scope on the left side of 'equals'. Consider
swapping the expressions on either side of 'equals'.
In SQL I have written a similar query as below so I know SQL suppports it:
SELECT * FROM Address a
INNER JOIN SPATIALTABLE b
WITH(INDEX(geog_sidx))
ON b.geom.STIntersects(a.PointGeography) = 1

Try something like this:
var joinQuery =
from spQ in spatialTableQuery
from mnQ in MainQuery
where spQ.Polygon.Intersects(mnQ.PointGeography) = 1

Related

translate sql inner join into django objects.filter

I wanted to know how to translate this sql query into django's object.filter method
SELECT "accounts_customuser"."id"
FROM "accounts_customuser"
INNER JOIN "accounts_customuser_groups"
ON ("accounts_customuser"."id" == "accounts_customuser_groups"."customuser_id")
INNER JOIN "auth_group"
ON ("auth_group"."id" = "accounts_customuser_groups"."group_id")
where ("auth_group.name" IS NOT NULL)
in an accounts application I made a custom user model, there is also the group model that comes into play
in the django doc I saw an example but I would like to know how to apply it well for my case
q1 = Entry.objects.filter(headline__startswith="What")
q2 = q1.exclude(pub_date__gte=datetime.date.today())
q3 = q1.filter(pub_date__gte=datetime.date.today())
thank for any help.

Is there any way to use raw sql or i'm stuck with laravel-eloquent?

I'm trying to migrate an application developed in 2007 and add and api to it so I can easy develop and sync data with the new App I started a laravel project with the old database just to create the api the old database diagram look like this: Too many relationships and crazy polymorphic ones at that.
I want to migrate my query to laravel eloquent but I couldn't do it in time I tried to do it with eloquent but it took too much time is there any way to use raw sql like this or i'm stuck with eloquent this is my laravel code : here
the sql query looks like this
SELECT n.DOC_ID, n.TYP_ID, n.TYP_ID,
type_document.TYP_LIBELLE_AR, n.IND_ID,indication.IND_LIBELLE_AR,n.LAN_ID,
langue.LAN_LIBELLE_AR,
n.DOC_TITRE_PROPRE,
n.DOC_TITRE_COMPLEMENT,
n.DOC_TITRE_PARALLELE,
n.DOC_TITRE_ENSEMBLE,
n.DOC_NUMERO_PARTIE,
editeur.EDT_NOM_AR,
editeur.EDT_KEYWORDS,
n.DOC_LIEU_EDITION,
n.DOC_ANNEE,
n.DOC_EDITION,
periodicite.PER_LIBELLE_AR,
n.DIP_ID,
specialite.SPE_LIBELLE_AR,
n.COL_ID,
n.DOC_NUM,
n.COL_NUMERO,
n.COT_NOTICE,
n.SCL_ID,
n.SCL_NUMERO,
n.DOC_NBR_UNITE,
n.DOC_ILLUSTRATION,
n.DOC_FORMAT,
n.DOC_MATERIEL,
n.DOC_ISBN,
n.DOC_ISSN,
n.DOC_NBR_EXEMPLAIRE,
n.STA_ID,
n.REL_VOLUME,
n.PAY_ID,
n.DOC_AGENCE,
n.DOC_PRET_INTERNE,
n.DOC_PRET_EXTERNE,
n.DOC_KEYWORDS,
n.CREATE_DATE,
n.UPDATE_DATE,
statut_notice.STA_LIBELLE_AR,
notice_auteur.VED_ID,
notice_auteur.FON_ID,
notice_auteur.AUT_TYPE,
GROUP_CONCAT(DISTINCT vmath.VED_NOM) AS mats,
vmath.VED_KEYWORDS,
GROUP_CONCAT( DISTINCT vauth.VED_NOM) AS auths,
vauth.VED_KEYWORDS,
GROUP_CONCAT( DISTINCT notice_exemplaire.EXP_COTE) AS examp_cote,
GROUP_CONCAT( DISTINCT notice_exemplaire.LOC_ID) AS exmp_location
FROM notice n
INNER JOIN editeur ON editeur.EDT_ID =n.EDT_ID
INNER JOIN type_document ON type_document.TYP_ID = n.TYP_ID
INNER JOIN langue ON langue.LAN_ID = n.LAN_ID
INNER JOIN statut_notice ON statut_notice.STA_ID = n.STA_ID
INNER JOIN indication ON indication.IND_ID = n.IND_ID
INNER JOIN notice_exemplaire ON n.DOC_ID = notice_exemplaire.DOC_ID
LEFT JOIN specialite ON n.SPE_ID = specialite.SPE_ID
LEFT JOIN periodicite ON periodicite.PER_ID = n.PER_ID
INNER JOIN notice_auteur ON n.DOC_ID = notice_auteur.DOC_ID
INNER JOIN vedette vauth ON notice_auteur.VED_ID = vauth.VED_ID
LEFT JOIN notice_matiere ON n.DOC_ID = notice_matiere.DOC_ID
LEFT JOIN vedette vmath ON notice_matiere.VED_ID = vmath.VED_ID
GROUP BY n.DOC_ID
1:
For something like this you can use DB::select('YOUR-QUERY').
DB::select('...') calls select() on the underlying Connection class so it's not the same as using DB::table('...')->select('...') which is calling the select method on the Builder class.
For more information on running raw queries you can refer to the documentation.

LEFT JOIN with AND operator using Criteria API

I am trying to build dynamic queries using JPA and Criteria API but without metamodels.
With the tables:
Foo:
ID
1
2
3
4
Bar:
ID FooID Number
1 2 44
2 2 55
3 3 55
I want to retrieve all Foo entities where no matching Bar has Number 44. (Expecting Foo 1, 3, 4)
The SQL should look something like this:
select distinct *
from Foo foo0_
left join Bar bar0_ on foo0_.ID=bar0_.FooID and bar0_.Number=44
where bar0__.id is null;
My code looks something like this:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
Root<Foo> fooRoot = cq.from(Foo.class);
cq.select(fooRoot).distinct(true);
List<Predicate> allPredicates = new ArrayList<Predicate>();
List<Predicate> orPredicates = new ArrayList<Predicate>();
List<Predicate> andPredicates = new ArrayList<Predicate>();
andPredicates.add(cb.equal(fooRoot.join("bars", JoinType.LEFT).get("number"), 44));
andPredicates.add(cb.isNull(fooRoot.join("bars", JoinType.LEFT).get("ID")));
orPredicates.add(cb.and(andPredicates.toArray(new Predicate[andPredicates.size()])));
allPredicates.add(cb.or(orPredicates.toArray(newPredicate[orPredicates.size()])));
cq.where(allPredicates.toArray(new Predicate[allPredicates.size()]));
TypedQuery<Foo> query = em.createQuery(cq);
query.getResultList();
But that generates this SQL:
select distinct *
from Foo foo0_
left outer join Bar bar1_ on foo0_.id=bar1_.FooID
left outer join Bar bar2_ on foo0_.id=bar2_.FooID
where bar1_.Number=44 and (bar2_.id is null);
and returns no Foo.
Any ideas? Thank you!
You don't specify which JPA implementation this is for, and clearly the SQL may differ for each.
That aside, your joining is wrong. Each join call will do a JOIN, and you only want 1 join if what you write is correct. Also you can make use of JPA 2.1 "ON" conditions on the join (rather than putting it in the WHERE).
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
Root<Foo> fooRoot = cq.from(Foo.class);
cq.select(fooRoot).distinct(true);
Join barJoin = fooRoot.join("bars", JoinType.LEFT);
Predicate onCond = cb.equal(barJoin.get("number"), 44);
barJoin.on(onCond);
Then do the same as your question except using the barJoin; no idea what those AND/OR conditions are trying to do - your suggested SQL has none of that.

hibernate - HQL joins on many clauses

I've been reading Hibernate documentation, but I haven't found anything that would explain how to do the following.
I have the following SQL code that I'm trying to convert to HQL:
SELECT {msg.*}, {cmd.*}
FROM Schema.Messages AS msg
LEFT OUTER JOIN schema.send_commands AS cmd
ON cmd.message_key = msg.unique_key
AND ( lower(cmd.status) IN (lower('failed') ) )
WHERE msg.sequence_received < 10";
The mainissue I'm having is that I'm unable to have two clauses on a LEFT OUTER JOIN. HQL allows me to have
ON cmd.message_key = msg.unique_key
, but how do I add the
AND clause 2?
You can add extra join conditions using with keyword, something like this (depends on your mapping):
SELECT m, c
FROM Message m LEFT JOIN m.commands c WITH (lower(c.status) = 'failed')
WHERE m.sequenceReceived < 10
See also:
16.3. Associations and joins

convert sql to linq sample

I've got a sql statement, but I can't get it working in linq. Can someone show me how I can write the following sql statement as linq?
SELECT * FROM mobileApplication
LEFT JOIN videoMobile ON mobileApplication.id = videoMobile.mobileApplicationId
AND videoMobile.videoId = 257
It's a left join with a where statement on the right table. It works in sql server 2005, but I'd like to write it in linq.
I didn't verify the syntax, but try this...
var mobileApplications = from ma in mobileApplication
join vm in videoMobile on ma.id equals vm.mobileApplicationId into j1
from j2 in j1.DefaultIfEmpty()
where vm.videoId == 257
select ma;
There is a product that will do this for you. I have found it very useful. The product name is Linqer. It is not free, but not expensive, and offers a 30 day trial. I have found very few queries it is not able to convert. It has worked well for me.
http://www.sqltolinq.com/
Its something like:
from ma in mobiledApplication.DefaultIfEmpty()
join vm in videoMobile on new { mobileApplicationId = ma.id, videoId = 257 } equals new { mobileApplicationId = vm.mobileApplicationId, videoId = vm.videoId } into videoMobileApplication
from vma in videoMobileApplication
select vma
The keys being the default if empty and using anonymous objects on the join criteria to incorporate 257 into the join.
I am pretty sure that using a where clause for the 257 will achieve the same result though...
Try some like this:
var query =
from m in mobileApplication
join v in videoMobile
on m.id = v.mobileApplicationId and v.id = 257
select m;
See here:
http://msdn.microsoft.com/en-us/library/bb397676%28v=VS.100%29.aspx
http://msdn.microsoft.com/en-us/magazine/cc163400.aspx