I have 3 tables:
Table: Company, Columns: Id, Name
Table: User, Columns: Id, Name, CompanyId
Table: CompanyOwnerInfo, Column: Id, CompanyId, OwnerName.....
CompanyId column in both User and CompanyOwnerInfo tables are mapping to Company.Id
My question is how to create a One-to-One mapping for User and CompanyOwnerInfo table without Company table involved? because when I use User object to getting CompanyOwnerInfo there is no necessary to join the Company table?
public UserMap()
{
References(x => x.Company, "CompanyId");
References(x => x.CompanyOwnerInfo, "CompanyId")
.PropertyRef(compOwner => compOwner.Company)
.Fetch.Join()
.Not.LazyLoad() // if needed
.ReadOnly(); // important otherwise you have Exception on save because both References want to write to the same column
}
Related
I have 3 tables:
numbers (id, name)
food (id, name)
numbers_food (number_id, food_id, price_per_ad, price_per_ch)
How I can to get a price_per_ad and price_per_ch data for each food_id from numbers_food relationship table?
Just define relationships in models.
In NumberFoodModel:
'food' => array(self::BELONGS_TO, 'Food', 'food_id'),
In FoodModel:
'number_food' => array(self::HAS_MANY, 'NumberFood', 'food_id'),
Now in your code just use
Food::model()->with('number_food')->findByPk($id)
I have the database just like this
==== cis_policy_registration====
id
policy_id
email_id
policy_start_date
==== cis_policy_family_details===
id
policy_id
is_main_applicant
firstname
lastname
gender
Now how to make the relation between models with the policy_id (both tables),
I want to take firstname and lastname in registration model and check is main applicant
that must list in CGridView
who can solve this problem
thanks in advance
The relation between these two tables should be handled from the "main" model (Policy), so in Policy model class you should have:
'policy_reg' => array(self::HAS_ONE, 'PolicyRegistration', 'policy_id'),
'policy_details' => array(self::HAS_ONE, 'PolicyDetails', 'policy_id'),
And then:
$policy = Policy::model()->with(array('policy_details'))->findByPk($pk);
$policy->policy_details->is_main_applicant;
...
And in CGridView you can print the relational value like this (after sending CActiveDataProvider object from Policy model):
'policy_details.firstname'
or
array(
'name'=>'Firstname',
'value'=>'$data->policy_details->firstname',
),
I'd like to set up a CGridView. I'm looking to display data from 2 different tables in one view. The data is from a table called student, and another table called employee.
employee is refereed by student(reg_no)
student table
reg_no (primary key)
s_name
dept
f_name
employee table
e_no(primary key)
e_name
desig
salary
reg_no(foreign key)
I want to display the (reg_no,s_name,f_name) from student and (design,salary) from employee table in a single grid view, can anyone please give an idea or any tutorial,
First make sure that your models and relationships are defined properly. Check the models to make sure that relationships are there.
e.g. you shall have an entry like this in your employee model;
function relations() {
return array(
'reg_no'=>array( self::BELONGS_TO, 'Student', 'reg_no' ),
);
}
Use CActiveDataProvider in the CGridView instead of an array as the data source.
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$model->searchEmplyees(),
.......
.......
Add another search cirteria to your model that returns the data as a CActiveDataProvider.
public function seachEmployees()
{
$criteria=new CDbCriteria;
$criteria->alias = 'i';
$criteria->compare('id',$this->id);
.......
.......
$criteria->join= 'JOIN 'your table name' d ON (i.id=d.id)';
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'order_in_sna ASC',
),
));
}
I have just typed this code in for your reference so you understand how Yii is handling all of this for you. This is another good example, again from the Yii Framework site.
Have a legacy database with mapping table structures like the following. I am trying to figure out how to fluently map this type of relationship.
There are multiple parent tables that use a mapping table to store notes.
The parent tables look like the following:
P1 Table
ID iSomething
P2 Table
ID iSomethingElse
There is a mapping table that will take a parent table and map it to a note table.
Mapping Table
ID i_RecordUniqueID
ID i_NoteID
ID i_RecordID
The column i_RecordID contains a numeric value indicating which parent table the i_RecordUniqueID value came from. The mapping table only has those three columns and is a ternary primary key.
Here is the note table:
Note Table
ID i_NoteID
The query to find table P1's notes is as follows:
Select n.*
from P1 p
inner join Mapping m on p.iSomething = m.i_RecordUniqueID and m.i_RecordID = 1
inner join Note n on m.i_NoteID = n.i_NoteID
The query to find table P2's notes is as follows:
Select n.*
from P2 p
inner join Mapping m on p.iSomething = m.i_RecordUniqueID and m.i_RecordID = 2
inner join Note n on m.i_NoteID = n.i_NoteID
In my Parent tables mapping file, I have an association like the below. I don't know how to add the i_RecordID constraint.
HasManyToMany<Note>(x => x.Notes)
.Table("Mapping")
.ParentKeyColumn("i_RecordUniqueID")
.ChildKeyColumn("i_NoteID")
.Cascade.All();
FluentNHibernatew does not yet support ManyToAny mapping. you could map it for readonly access
// P1Map()
HasManyToMany(x => x.Notes)
.Table("Mapping")
.ParentKeyColumn("i_RecordUniqueID")
.Where("i_RecordID == 1")
.ChildKeyColumn("i_NoteID")
.Cascade.All();
// P2Map()
HasManyToMany(x => x.Notes)
.Table("Mapping")
.ParentKeyColumn("i_RecordUniqueID")
.Where("i_RecordID == 2")
.ChildKeyColumn("i_NoteID")
.Cascade.All();
or you have to create a component
ICollection<TableToNote> Notes;
public TableToNoteMap()
{
ReferencesAny(x => x.Parent).IdentityColumn("i_RecordUniqueID").MetaTypeColumn("i_RecordID")...;
References(x => x.Note);
}
I have a table that contains information from many customers
ID | employeename | customerId
------------------------------
1 | employee1 | 188
2 | employee2 | 188
3 | employee3 | 177
Now I would like to get only those employees, whose customerId is 188. How do I map this with Fluent NHibernate so, that on update and delete there would also be WHERE customerId = 188 ?
Current Mapping is something like:
Id(x => x.Id);
Map(x => x.Name).Column("employeename");
Map(x => x.CustomerId).Column("customerId");
Adding Where("customerId = 188") only results custom where clause in SELECT. I would need following UPDATE-clause to happen on saveorupdate.
UPDATE employees SET employeename="employ" WHERE ID = 2 AND customerId = 188;
You are thinking wrong with this SQL mind in your head.
1) Add HasMany( x => x.Employees ).Inverse().AsSet(); in your Customer class.
2) Add References( x=> x.Customer ); in your Employee class.
This is called bidirectional mapping.
Look here: http://www.progware.org/Blog/post/NHibernate-inverse3dtrue-and-cascade3dsave-update-demo.aspx
The idea is that you create your objects and you assign values to them. After that NHibernate executes SQL statements if you have proper mapping files. Dont write your sql queries and then forcing NHibernate to generate exactly the same ones. Instead write your mappings and see what SQL NHibernate generates and try to optimize it.
PS: Dont forget to add the cascade...