How to generate JOIN ON query using ORMLite - ormlite

I would like to JOIN 2 tables using ORMLite while there is no ORMLite's foreign key definition between the tables.
To better explain my problem, the query I want ORMLite to generate should look like this:
SELECT Order.ID
FROM Order
JOIN MyTmpTable
ON Order.CustomerID=MyTmpTable.CustomerID;
Unfortunately, the join(...) method available in ORMLite requires explicit foreign key definition between the tables.
Join with another query builder. This will add into the SQL something
close to " INNER JOIN other-table ...". Either the object associated
with the current QueryBuilder or the argument QueryBuilder must have a
foreign field of the other one. An exception will be thrown otherwise.
But neither Order nor MyTmpTable has foreign key definition. MyTmpTable definition is the following:
#DatabaseTable
class MyTmpTable {
...
#DatabaseField
private Long longId;
...
}
And I really can't change it to
#DatabaseTable
class MyTmpTable {
...
#DatabaseField(foreign = true)
private Order order;
...
}
because it serves as a generic temporary join table.
Something like joinOn(...) would solve my problem, but it is probably not available in ORMLite.
Have you any ideas how could I join 2 tables with no foreign attribute defined?

Related

How can I join two tables by a foreign key table in Entity Framework?

I am trying to join two tables by a foreign key table in linq.
The two tables are
Items and Classes, and the foreign key table is ItemClasses (ItemId, ClassId).
My context does not have a DBSet for the foreign key table, and when I try to add it I get a model creation error.
When I saw the error, I noticed that this code referred to the foreign key table
modelBuilder.Entity<Classes>()
.HasMany(e => e.Items)
.WithMany(e => e.Classes)
.Map(m => m.ToTable("ItemClasses").MapLeftKey("ClassId").MapRightKey("ItemId"));
So it looks like I should be able to refer to the items through the class, but how do I join the tables?
I'd like to do something like this
query = from ig in myCtx.Items.AsNoTracking()
//join di in myCtx.ItemClasses.AsNoTracking() on ig.Id equals di.ClassId
join c in myCtx.Classes.AsNoTracking() on di.ClassId equals c.Id
join dd in myCtx.SalesAssociates.AsNoTracking() on dd.Id equals ig.SalesAssociateId
How do I do joins when the fk table is not in my context, but is referred to in one of the tables?
First, you have a configuration error. With HasMany / WithMany you are actually configuring the automatic "link" table, so
m.ToTable("Classes")
should be
m.ToTable("ItemClasses")
or how exactly you want that table to be named in the database.
Second, when working with EF, it's always preferred to use navigation properties rather than joins. In case of many-to-many relationship with auto link table, using navigation properties is mandatory. EF will produce the necessary joins for you.
So instead of join your would use something like this:
query = from ig in myCtx.Items.AsNoTracking()
from c in ig.Classes
...

how to establish a relationship between two columns in one table

I want establish a one-to-one relationship between two columns (a program code and a test code) in the same table. I want all tests with the same test code to have the same program code.
My first thought was to use a UDF to find cases where the same test code corresponds to two different programs. I learned that this won't work because t-sql only checks UDFs in check constraints after INSERTS -- not after UPDATES
why is t-sql allowing me to violate a check constraint that uses a UDP?
My next thought was to move the logic from the UDF into the check constraint itself. But t-sql is saying that sub-queries are not allowed in the check constraint. This also means I can't use EXISTS syntax (which I think also uses a sub-query).
ALTER TABLE [dbo].[mytable] WITH CHECK ADD CONSTRAINT [oneProgramPerTest] CHECK
(
(select COUNT(*)
from mydb.dbo.mytable u1
inner join
mydb.dbo.mytable u2 on u1.testcode=u2.testcode and u1.progcode <> u2.progcode
)=0
)
Unless there is some way to enforce this logic without (1) a udf or (2) a subquery then it seems like I need to create a "dummy" table of program codes and then enforce a one-to-one relationship between test codes from myTable and the dummy table. This seems really ugly so there has got to be a better way. Right?
Have you read about normalization (and if you haven't why are you designing a datbase?). You should havea structure with
tableA
id (PK)
programcode
other fields
tableB
programcode (PK)
testcode
Add a formal foreign key between the two tables and define program code as the PK in tableb.
Then to get the data you want:
select <Name specific fields, never use select *>
from tableA a
join tableB b on a.programcode = b.programcode

setIntegrityCheck in Zend Selects with joins

I was looking at some questions that ask how to do joins in Zend Framework queries, but the answer is always something like "just do setIntegrityCheck(FALSE)".
My question is: why do I need to do this?
It seems to me disabling "integrity checks" is not the proper way of making this work. In my particular case, I'm using a MySQL database with some InnoDB tables with foreign keys, so for example:
CREATE TABLE IF NOT EXISTS `tableA`
(
`id` CHAR(6),
`name` VARCHAR(255),
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `tableB`
(
`tableA_id` CHAR(6),
`somefield` VARCHAR(255),
PRIMARY KEY (`tableA_id`)
) ENGINE=InnoDB;
ALTER TABLE `tableB` ADD FOREIGN KEY fk1 (`tableA_id`) REFERENCES `tableA` (`id`);
(this is a very simplified version of my DB)
And, my query code looks like this:
$table = new Zend_Db_Table('tableB');
$select = $table->select(TRUE)
->join(array('a' => 'tableA'), 'tableB.tableA_id = a.id');
$result = $table->fetchAll($select);
This is giving me the "Select query cannot join with another table" exception unless I add the setIntegrity(FALSE) to my $select.
Calling setIntegrityCheck(false) is the proper way to do a join; if you are using Zend_Db_Table and Zend_Db_Table_Select, you can't join unless you disable the integrity check.
The integrity check is simply in place to make sure the query DOES NOT use multiple tables, and when in place, ensures that the Zend_Db_Table_Row objects can be deleted or modified and then saved because the row data is exclusive to a single table, and is not a mix of data from different tables.
To indicate that you WANT to use multiple tables, then specify setIntegrityCheck(false) to let Zend Framework know that it is intentional. The result is that you get a locked row which cannot call save() or delete() on.
Here is a quote from the reference guide on Zend_Db_Table - Advanced Usage (skip to example 27.
The Zend_Db_Table_Select is primarily used to constrain and validate
so that it may enforce the criteria for a legal SELECT query. However
there may be certain cases where you require the flexibility of the
Zend_Db_Table_Row component and do not require a writable or deletable
row. for this specific user case, it is possible to retrieve a row or
rowset by passing a FALSE value to setIntegrityCheck(). The resulting
row or rowset will be returned as a 'locked' row (meaning the save(),
delete() and any field-setting methods will throw an exception).
See also: One-to-Many Joins with Zend_Db_Table_Select
Ok, I did some research, and it isn't quite true that you have to call setIntegrityCheck(FALSE) in order to do joins.
The relevant code in the Zend_Db_Select class (i.e. the only place to find the very last word to this argument), contains this code:
if ($this->_integrityCheck !== false) {
foreach ($fields as $columnEntry) {
list($table, $column) = $columnEntry;
// Check each column to ensure it only references the primary table
if ($column) {
if (!isset($from[$table]) || $from[$table]['tableName'] != $primary) {
require_once 'Zend/Db/Table/Select/Exception.php';
throw new Zend_Db_Table_Select_Exception('Select query cannot join with another table');
}
}
}
}
So, actually, it checks to see if all the selected fields in the query belong to the "primary table". A query does not necessarily have to return all the fields in the involved tables.
Coming back to the example in my question, it turns out this does work:
$table = new Zend_Db_Table('tableB');
$select = $table->select(TRUE)
->join(array('a' => 'tableA'), 'tableB.tableA_id = a.id', NULL); // <-- notice the third parameter here
$result = $table->fetchAll($select);
This new query only returns the fields from tableB, but you can add where conditions on any of the tables, as you would normally do with SQL, with no problem.

Entity Framework Discriminated Associations

Is there any way of getting discriminated associations to work in Entity Framework 4? That is, where we have the following tables
TableA
RelatedEntityTypeId
RelatedEntityTypeKey
TableB (1)
Id
TableC (2)
Id
TableD (3)
Id
and I want to have three associations on the entity for TableA:
TableB
TableC
TableD
which are defined by the RelatedEntityTypeId and RelatedEntityTypeKey fields...when RelatedEntityTypeId = 1, then the association is to EntityB, when RelatedEntityTypeId = 2, then the association is to EntityC, etc.
Thanks.
I don't know your purpose of doing this. I have used following approach to solve similer problem.
You can define a base type for all three tables (A,B,C). And when you want retrieve a object use a generic method for all tables (which returns a base object). And then you can check the type of the returned object to get the A,B,C object.
TableBase
Id
TableB (1):TableBase
TableC (2):TableBase
TableD (3):TableBase

From SQL with Left Outer Join to JPQL or Native SQL

Hiya all, my problem is related to converting one of the Sql with left join into jpa and entity structure, but i am stucked with it here is my sql
SELECT
*
FROM X_TABLE LEFT OUTER JOIN Y_TABLE
ON
TO_CHAR (X_TABLE.TIME1, 'HH24:MI') =
TO_CHAR (Y_TABLE.TIME1, 'HH24:MI')
AND
TO_DATE(Y_TABLE.DATE1) = TO_DATE('10/10/2010','dd/MM/yyyy')
AND
Y_TABLE.Z_TABLE_ID =X_TABLE.Z_TABLE_ID,
Z_TABLE
Where X_TABLE.Z_TABLE_ID =Z_TABLE.ID
Y_TABLE has foreign key of X_table
but when i query with this sql , X_TABLE which has no foreign key of Y_TABLE ,
where will my columns of Y_TABLE be stored in?
the relationship between Y_TABLE and X_TABLE is ManyToOne ,
so in the Y_TABLE entity i have #ManyToOne X_TABLE field,
when i map inversely this relationship in X_TABLE via mapped
i am having a Y_TABLE list
when i query this sql i am getting just a row with two tables columns?
but in entity meaning i am having a list of Y_TABLE?
how i can get the all returning columns in one entity, what should i do for that?
thanx all
system we have been working like below
eclipselink 2.0.1,Glassfish 3.0.1,JSF 2
Your query seems very complex. Perhaps start by explaining your object model, and what you are trying to do, and what you want back from your query.
Your function usage seems odd, why do you want to compare your times as chars and your chars as dates?
If your database is very cryptic, you may consider defining a view and mapping to it instead.