I have two tables that I want to map to one class that will looks like:
CUSTOMER_INFO_CLASS.cs
----------------------
Id (CUSTOMER table)
CustomerName (CUSTOMER table)
CustomerTypeDesc (CUSTOMER_TYPE table)
I tried to do it with join, as follows:
Table("CUSTOMER");
Id(x => x.ID).Length(10).Column("CustomerId");
Map(x => x.CustomerName);
Join("CUSTOMER_TYPE", m =>
{
m.Optional();
m.Map(x => x.CustomerTypeDesc);
m.KeyColumn("CustomerType");
});
The problem is that the field with whom I'm trying to link the two tables is not a primary key in any of them. (And by default the join done by the field that defined as ID)
So I found that for the CUSTOMER_TYPE table I can define the field by “KeyColumn”.
How can I define that the related column in the CUSTOMER table will be CustomerTypeCode and not CustomerId? (if I can at all)
At the end the sql query should looks like:
Select Id, CustomerName, CustomerAddress, CustomerTypeDesc
From CUSTOMER t1
Left join CUSTOMER_TYPE t2
On t1.CustomerTypeCode = t2.CustomerType
If the Customer table maps the CustomerType member to the primary key of the CustomerType table, then Hibernate should do the join automatically for you.
Is there a reason why the CustomerType is not linked by a normal foreign key reference?
Related
I have been working on how to map an entity property to a column in another table using multiple joins (or a subquery), but I am really struggling to find where to start.
I have create a SQL Fiddle that demonstrates what I want to do. A User entity should contain a property called Employee that selects the name from the employee table
SET #uid = 2;
SELECT Employee.Name
FROM Employee
JOIN Company ON Employee.CompanyId = Company.Id
WHERE Company.CompanyNo = (SELECT UserEmployee.CompanyNo
FROM UserEmployee
JOIN User ON UserEmployee.UserId = User.Id
AND User.Id = #uid)
AND Employee.EmployeeNo = (SELECT UserEmployee.EmployeeNo
FROM UserEmployee
JOIN User ON UserEmployee.UserId = User.Id
AND User.Id = #uid)
http://sqlfiddle.com/#!9/cbac3/2
Basically, a User record is linked with a Employee using a relationship table (UserEmployee), however this is a 1-0 relationship.
We are not using Ids as foreign keys, instead each Employee has a EmployeeNo and has a 1-1 relationship with a Company that has it's own CompanyNo, so the composite foreign key for the UserEmployee table is made up of the Employee and Company Numbers.
I cannot link to the EmployeeId directly in the UserEmployee table as in the actual system employee records are duplicated (for history keeping reasons) and there is a third table added into the mix.
Thank you
If I have an array of IDs from a table (table1) in my database. Is there a way of querying another table (table2) to select all the records where a column equals a value equal to one of the IDs from table1.
My code so far is:
LabQuestion.where("product_id=#{Product.where(:brand_id => brand_id).pluck(:id)}")
In this code, I am trying to retrieve all the Lab Questions which are linked to all the products from a brand. This code does not work, but I've tried to demonstrate my needs.
Assuming you have setup your relations properly, you can use joins to join the two tables and query them like this:
LabQuestion.joins(:product).where(:products => { :brand_id => brand_id })
You can use includes instead of joins as below
LabQuestion.includes(:product).where(:products => { :brand_id => brand_id })
In the following FluentNHibernate mapping:
public LawbaseAssetMap()
{
Table("PRASSET");
Id(x => x.Id).Column("PRA_RECNUM");
Join("PRSTOCK", m =>
{
m.Fetch.Join();
m.Optional();
m.KeyColumn("PRS_ASSRN");
m.Map(t => t.Certificated).Column("PRS_CERT").CustomType("YesNo");
});
}
I am performing an outer join from the table PRASSET to the table PRSTOCK. The join is between PRSTOCK.PRS_ASSRN and PRASSET.PRA_RECNUM (the primary key of PRASSET).
How would I create the equivalent join, but instead of joining onto PRASSET's primary key, join on to another field instead?
David have a look on following link, as i thing that it might help
Fluent NHibernate - Mapping a property to a column on a joined table
also this might help
ReferencesAny(x => x.Author)
.EntityTypeColumn("Type")
.EntityIdentifierColumn("Id")
.IdentityType<int>();
See more here.
Hope this helps... and now really holliday :) see u
Situation:
TableParent with 2 primaryKeys, ParentKey1 and ParentKey2
TableChild with 1 primaryKey, ChildKey
TableConnector with columns ParentKey1, ParentKey2 and ChildKey
This is where I think I should go with my Linq query. Notice I'm fetching all childs belonging to a parent so I have it's keys as parameters.
var query = from conn in db.TableConnector
join child in db.TableChild on conn.ChildKey equals child.childKey
join par in db.TableParent on conn.ParentKey1 equals par.parentkey1 into connGroup
from co in connGroup
where co.ParentKey1 == Parameter1
Select child;
Well I tthink this works up to a point, let's say if parent had only one key, am I right?
I guess I have to join some more into a second group but I'm currently lost.
Firstly, you don't have two primary keys on your table. You can only have one primary key (hence the name primary). It sounds like you have a composite primary key, which means a key that is composed of more than one column.
I'm not sure what problem you are trying to solve, but it seems to be retrieving all TableChild rows for a given TableParent key. It should be something like this:
db.TableParent
.Single(parent => parent.ParentKey1 == key1 && parent.ParentKey2 == key2)
.TableConnectors.Select(connector => connector.TableChild)
If you have your tables mapped correctly on your Linq-to-Sql designer then you don't have to manually join them - that's what the Linq-to-Sql code generation does for you.
For example, when you have a TableConnector you will be able to retrieve the TableChild rows for it using something like this
TableConnector t = db.TableConnectors.First();
List<TableChilds> tableChilds = tableConnector.TableChilds.ToList();
tableParent only needs one primary key (it's own Id) and tableChild needs one (it's Id)
the connectorTable only needs two columns to make the many-to-many-relation work:
ParentId and ChildId
For each relation between a parent and a child you simply add one row to the connectorTable, and in order to retrieve the results try this:
select * from tableParent
inner join connectorTable
on tableParent.Id = connectorTable.ParentId
inner join tableChild
on connectorTable.ChildId = tableChild.Id
If your reason for multiple keys in the parent table is that you want to create relations between parents as well this needs to be addressed either via a relation field in the parent table (one-to-many) or another relationTable (many-to-many)
Given these tables:
create table Orders (
Id INT IDENTITY NOT NULL,
primary key (Id)
)
create table Items (
Id INT IDENTITY NOT NULL,
primary key (Id)
)
create table OrdersItems (
OrderId INT not null,
ItemId INT not null,
primary key (OrderId, ItemId)
)
Is it possible to use HQL/criteria API to contruct a query that results in the following SQL:
SELECT
[OrderId], [ItemId]
FROM
[OrdersItems]
I've tried both of these approaches:
var hqlResults = session
.CreateQuery("select order.id, item.id from Order order inner join order.Items item")
.List();
var criteriaResults = session
.CreateCriteria<Order>()
.CreateAlias("Items", "item", NHibernate.SqlCommand.JoinType.None)
.SetProjection(Projections.Property("id"), Projections.Property("item.id"))
.List();
But both approaches insist on generating a join (or fail because the join isn't present, in using criteria), resulting in SQL such as:
select order.Id,
item.Id
from Orders order
inner join OrdersItems ordersItems
on order.Id = ordersItems.ArticleId
inner join Items item
on ordersItems.CategoryId = item.Id
Is there any way to have NHibernate generate a query that selects columns only from the join table, without requiring a join?
I doubt that there's a way to do it using HQL, because HQL deals witn NHibernate entities and OrderItems is not an entity. In this case it looks like you're not actually using any ORM features, so you can simply do a SQL query - via NHibernate if you wish. Just call ISession.CreateSQLQuery().
Edit:
I suspect that the reason NHibernate insists on doing the join is this: you've asked it for the Id properties of Order and Item entities, so it must ensure that there are actually rows in the Order and Item table for those IDs. It's possible that a row exists in the OrderItems table with IDs that don't exist in Order or Item. Sure, it would be bad database design to do that and it's unlikely, but NHibernate can't be sure that this is not the case unless it looks at the table schema and sees the appropriate foreign keys - but I doubt that it does things like that.
This is just my speculation, though. You could ask on the NHibernate forum for a more definitive answer from the developers.