Suppose say I have Order, Items, OrderItems tables with Order and Items having n:n relationship and OrderItems being associative table. I have seen below two approaches for defining them.
1.Create Order and Items entities with "HasMany" relationship with OrderItems.
2.Create Order, Items and OrderItems entities with Order and Items having "ManytoMany" relationship and "OrderItems" containing Order and Item properties.
I have approach 1 which works fine but would like to know what approach 2 does.
If the relationship between Items and Orders is simple (merely that the relationship exists), then you would do a ManyToMany mapping between Items.Orders and Orders.Items. This would result in NHibernate generating and managing a simple cross reference table containing the two foreign keys.
On the other hand, if there is additional information that you need to record along with the two foreign keys, you must use a distinct entity or value object to capture that information, using HasMany on both sides.
Classes:
Order
Id
Name
OrderItems
Item
Id
Name
OrderItems
OrderItem
Id
Order
Item
Quantity
Mappings:
Order:
Id(c => c.Id);
Map(c => c.Name);
HasMany(c => c.OrderItems).KeyColumn("OrderId");
Item:
Id(c = c.Id);
Map(c => c.Name);
HasMany(c => c.OrderItems).KeyColumn("ItemId");
OrderItem:
Id(c => c.Id);
Map(c => c.Quantity);
References(c => c.Order);
References(c => c.Item);
Related
Given the example at http://notherdev.blogspot.com/2012/01/mapping-by-code-inheritance.html
I have a base class Party and two concrete classes (Company, Person)
I would like to use Table Per Hierachy (Single Table), but my ids are only unique per concrete type.
i.e. Company and Person may have matching Id's
Is there any way to include the discriminator value in the Id as a composite id?
But still be able to call Get<>(id)?
How about this (Fluent):
public class PartyMap : ClassMap<Party>
{
public PartyMap()
{
Table("Parties");
CompositeId<CompositeIdType>(x => x.Id)
.KeyProperty(x => x.IdCompositePart)
.KeyProperty(x => x.Discriminator);
DiscriminateSubClassesOnColumn("Discriminator");
}
}
I wrote a joint query using NHiberNate, but I am getting a NHibernate.QueryException:not an association: Id
This is what it looks like with NHibernate library
TicketRequest ticketAlias = null;
Show showAlias = null;
IList<TicketRequest> results = UnitOfWork.CurrentSession.QueryOver<TicketRequest>(() => ticketAlias)
.JoinAlias(() => ticketAlias.ShowId, () => showAlias.Id)
.Where(() => showAlias.ShowDate >=DateTime.Now)
.List();
return results;
I just want a simple joint statement, and this is what it would have been in SQL
select * from TicketRequest as a join Show as b
on a.Show_id = b.Id
where ShowDate >=GETDATE()
Can someone help and let me know why I am getting a "not an association:Id" error. I have id in the "Show" table, it is a primary key.
Please advise. All helps are greatly appreciated.
You need to specify a many-to-one relation in joins. In your case that is the Show property.
IList<TicketRequest> results = UnitOfWork.CurrentSession.QueryOver<TicketRequest>(() => ticketAlias)
.JoinAlias(() => ticketAlias.Show, () => showAlias)
.Where(() => showAlias.ShowDate >= DateTime.Now)
.List();
PS: You shouldn't map both a many-to-one relation (Show) and an foreign key property (ShowID). Usually you only work with object relations when using an ORM. Only map the plain ID if you really need it for something, but even then only map it as read-only.
You don't have to specify the foreign keys / primary keys when querying with NHibernate. It's an ORM. You write object oriented queries. The keys and relations are specified in the mapping file.
A Join in an NHibernate query is simply specified by the property name with which you navigate to the other property.
That's what the error message means. Id is not an association.
I'm facing an issue in fetching data using relationship. Below is the detail:
I'm having two tables. First is item_master and Second is inventory table. Since both are having MANY_MANY relationship, so we are having another table named inventory_items with two fields (item_id, inventory_id).
Below is the relationship detail in ItemMaster Model:
'inventories' => array(
self::MANY_MANY,
'Inventories',
'inventory_items(item_id, inventory_id)'
),
'inventoryItems'=>array(self::HAS_MANY,'InventoryItems','item_id'),
I need to fetch Items of a particular Inventory only. For this, I'm implementing below filter criteria:
$criteria=new CDbCriteria;
$inventory_condition['condition']="inventoryItems.inventory_id=:inventoryID";
$inventory_condition['params'] = array(
':inventoryID' => $filter['inventory_id']
);
$inventory_condition['joinType']='INNER JOIN';
$criteria->with = array("inventoryItems"=>$inventory_condition);
$items=new CActiveDataProvider('ItemMaster',array('criteria'=>$criteria));
Problem:
Above code is returning me all the items with the required inventory. And if an item does not belong to that inventory than still it returns that Item but without inventory. I just need that only those Items should return which belong to a particular inventory.
You probably need to set together option to true:
$inventory_condition['together']=true;
But be careful if you are going to use it with SQL LIMIT.
I have 3 tables
task (Id,text,Contact_Id)
users(Id,name)
company(id,name)
and 2 junction tables
task_users (task_id,user_id)
task_companies (task_id,company_id)
note: contact_id may be refer to users table or company
How can I get task id, task text, contact name in one Criteria
This's example with QueryOver, but it almost like ICriteria.
Contact contact = null;
mappingSession.QueryOver<Task>()
.JoinAlias(() => task.Contact, () => contact)
.SelectList(list => list
.SelectGroup(task => task.Id)
.Select(task => task.Text)
.Select(() => contact.Name))
.TransformUsing(Transformers.DistinctRootEntity)
.List();
Other is a mapping. You can make base entity "Contact" and extend from it User and Company.
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?