i am developing an application in MVC3 using nhibernate
I have a two tables and i want to perform a join between the two and also i want to include multiple where conditions..
I am posting all the tables that are related so that it will clear the requirements:
First table is HobbyMaster:
HobbyId
HobbyName
Second Table is HobbyHome:
HobbyHomeId
HobbyHomeName
Third Table is HobbyDetail:
HobbyDetailId
HobbyId(Foreign Key)
HobbyHomeId(Foreign key)
Fourth Table is HobbyHomeAddress:
Id(primary key)
HobbyHomeId(Foreign key)
StateId(Foreign Key)
DistrictId(Foreign key)
Fifth Table is State:
stateid
statename
last Table is District:
districtid
districtname
I want to write a query like this:
select * from HobbyHomeAddress hobadd,
HobbyDetail hobdet
where hobdet.HobbyId=hobbyid
and hobadd.HobbyId=hobdet.HobbyId
and hobadd.StateId=stateid;
I tried this but it is not working and also gives me NUll
hobbyhomeaddress = session.CreateCriteria(typeof(HobbyHomeAddress))
.CreateAlias("HobbyDetail", "HobbyDetail", NHibernate.SqlCommand.JoinType.InnerJoin)
.Add(Expression.Eq("HobbyID", hobbyid))
.Add(Restrictions.Eq("HobbyHomeAddress.HobbyHomeId", "HobbyDetail.HobbyHomeId"))
.Add(Expression.Eq("ProvincialState.ProvincialStateID", stateid))
.List<HobbyHomeAddress>();
i am able to obtain the id's through ajax but i am not understanding how to fire the following query
Please help me
One possible issue:
.Add(Restrictions.Eq("HobbyHomeAddress.HobbyHomeId", "HobbyDetail.HobbyHomeId"))
This part of the join (in SQL) should be in your nhibernate mappings, you don't need to explicitly specify it.
Related
In MS Access, I am trying to implement a many-to-many table that will store 2-way relationships, similar to Association between two entries in SQL table. This table stores info such as "Person A and Person B are coworkers" "C and D are friends", etc. The table is like this:
ConstitRelationships
LeftId (number, primary key, foreign key to Constituents.ConstitId)
RightId (number, primary key, foreign key to Constituents.ConstitId)
Description (text)
Note that the primary key is a composite of the two Id fields.
Also the table has constraints:
[LeftId]<>[RightId] AND [LeftId]<[RightId]
The table is working ok in my Access project, except that I cannot figure out how to make an updateable query that I want to use as a datasheet subform so users can easily add/delete records and change the descriptions. I currently have a non-updatable query:
SELECT Constituents.ConstituentId, Constituents.FirstName,
Constituents.MiddleName, Constituents.LastName,
ConstitRelationships.Description, ConstitRelationships.LeftId,
ConstitRelationships.RightId
FROM ConstitRelationships INNER JOIN Constituents ON
(Constituents.ConstituentId =
ConstitRelationships.RightId) OR (Constituents.ConstituentId =
ConstitRelationships.LeftId);
If I ignore the possibility that the constituentId I want is in the leftId column, I can do this, which is updatable. So the OR condition in the inner join above is what's messing it up.
SELECT Constituents.ConstituentId, Constituents.FirstName,
Constituents.MiddleName, Constituents.LastName,
ConstitRelationships.Description, ConstitRelationships.LeftId,
ConstitRelationships.RightId
FROM ConstitRelationships INNER JOIN Constituents ON
(Constituents.ConstituentId =
ConstitRelationships.RightId) ;
I also tried this wacky iif thing to collapse the two LeftId and RightId fields into FriendId, but it was not updateable either.
SELECT Constituents.ConstituentId, Constituents.FirstName,
Constituents.MiddleName,
Constituents.LastName, subQ.Description
FROM Constituents
INNER JOIN (
SELECT Description, Iif([Forms]![Constituents Form]![ConstituentId] <>
ConstitRelationships.LeftId, ConstitRelationships.LeftId,
ConstitRelationships.RightId) AS FriendId
FROM ConstitRelationships
WHERE ([Forms]![Constituents Form]![ConstituentId] =
ConstitRelationships.RightId)
OR ([Forms]![Constituents Form]![ConstituentId] =
ConstitRelationships.LeftId)
) subQ
ON (subQ.FriendId = Constituents.ConstituentId)
;
How can I make an updatable query on ConstitRelationships, including a JOIN with the Constituent.FirstName MiddleName LastName fields?
I am afraid that is not possible. Because you use joins in your query over three tables it is not updatable. There is no way around this.
Here some detailed information about the topic: http://www.fmsinc.com/Microsoftaccess/query/non-updateable/index.html
As mentioned in the linked article one possible solution and in my opinion best solution for you would be the temporary table. It is a load of work compared to the easy "bind-form-to-a-query"-approach but it works best.
The alternative would be to alter your datascheme in that way that you do not need joins. But then denormalized data and duplicates would go rampage which makes the temporary table a favorable choice.
I have a few tables set up in Access as follows (forgive the slightly redundant example content):
Table 1:
- ID
- FirstName
- SecondName
Table 2:
- ID
- Details
- PersonID -> Table 1[ID]
Table 3:
- ID
- Group
- PersonDetails -> Table 2[ID]
Table 1 is the base table containing records and retrieving no other information. For example, it could store someone's first and second names, along with an autonumber ID.
Table 2 contains records which, amongst other things, contain a field that links to Table 1 and stores the ID of one of the records held there. With the lookup wizard I can choose to utilise all fields from Table 1, store the ID of the Table 1 record in the Table 2 field and also display the first and second names in the combobox on the form to make choosing a record more intuitive.
In table 3, I need to store the ID of one of the records in Table 2. However, I would also like to again display in the form combobox the first and second names from the related record (in Table 1) whose ID is stored in Table 2. I can't choose to utilise, for example, the PersonDetails field from table 2 as this just puts ID numbers into the combobox - I'd need to do something equivalent of:
Table 2[ID]->[FirstName]
Is this possible to do with the lookup wizard in Access or would I have to look into queries or VBA?
Thanks.
Your query for your combo should look something like this:
SELECT cp.ID, cp.ReferenceName, c.Company, p.FeePerHour
FROM (ClientProfile AS cp LEFT JOIN Clients AS c ON cp.ClientID = c.ID)
LEFT JOIN Pricing AS p ON cp.PricePlanID = p.ID;
The main problem with your query is that you're missing the Parenthesis that are needed when you have multiple joins. If you had another join, you'd need a second set of parenthesis.
I took some liberty and used table aliases. It makes SQL concise and more readable.
If this query still doesn't work it might be because you're trying to join "child tables" to the "main table" without using your Foreign Key fields as the joining field. If this were my database the SQL would look something like this:
SELECT cp.ClientProfileID, cp.ReferenceName, c.Company, p.FeePerHour
FROM (ClientProfile AS cp LEFT JOIN Clients as C ON cp.ClientID = c.ClientID)
LEFT JOIN Pricing AS p ON cp.ClientProfileID = p.ClientProfileID;
Personally, I basically never use just plain ID as a field name. And when creating a foreign key I usually use the same field name as what the original table has. There are exceptions, especially in the case where you need to link back to the same table more than once. Consider the case where you are tracking real estate properties and you have a Buyer and a Seller that are both entities (but different from each other) in the same People table. You would then need to name them something like BuyerID and SellerID but ultimately they would link back to the PersonID in the Person table.
So Here's the table design I would go for. Notice I changed Group to PriceGroup. Watch out for reserved words when programming, not only in SQL but any language. If you name your field Group at some point you'll be trying to "Group on Group" which sounds and looks bad, if nothing else.
Client:
- ClientID
- FirstName
- SecondName
ClientProfile:
- ClientProfileID
- Details
- ClientID (Foreign Key to Client)
Pricing:
- PricingID
- PriceGroup
- ClientProfileID (Foreign Key to ClientProfile)
Does anyone know a simple way of copying multiple table rows and it's related items?
In my simplified example I have two tables, one with a table for companies and one for their employees and I'd like to be able to clone entire companies with all their employees in a simple way.
[Companies]
- ID (Auto-increment)
- Name
[Employees]
- ID
- CompanyID (Foreign Key)
- Name
I've been playing around with the OUTPUT-clause but just managed to return the inserted IDs without a reference to the original row.
I just can't figure out how to link a inserted row to the original one?
If the insert-statement returned a table like this:
#mappingTable
-InsertedCompanyID
-OriginalCompanyID
I could run a statement like this to copy all employees:
INSERT INTO Employees (CompanyID, Name)
SELECT m.InsertedCompanyID, x.Name FROM #mappingTable m
INNER JOIN Employees x (x.CompanyID = m.OriginalCompanyID)
Or am I on the wrong path? Is there's a better way to accomplish this?
You can use the output clause of the merge statment to map between the old ID and the new auto incremented ID.
Have a look at this question: Using merge..output to get mapping between source.id and target.id
i have a table which store user name, hobby and city .hobby field contain different hobby joined using "," operator eg swimming, basket, cricket. I want to search user name who match at least one hobby according to my search criteria.
You should not have multiple attributes in one column. That's one of the number one rules of 3nf database design. Now you have to figure out ways to parse this data. This issue only gets worse and worse each and every day. Seperate the hobbies as multiple rows in your database.
I agree with #JonH that there shouldn't be more than one piece of information in a column. It stops the row being truly atomic.
But you are where you are, and you can use the LIKE clause to return rows that match a substring within a column.
Something like:
select hobbycolumn from hobbytable where hobbycolumn like '%swimming%'
for example
To do this properly you need to restructure your tables if possible. For what you are looking for a possible way would be to have 3 tables. I'm not sure who the city belongs to, so I put it with the user.
1 for user with the following cols:
id
name
city
A table for for hobbies:
id
name
And a user_hobbies join table that allows each user to have multiple hobbies, and each hobby to have multiple users:
id
user_id (foreign key)
hobby_id (foreign key)
Then searching for a user with a certain hobby is:
SELECT user.id, user.name FROM user
INNER JOIN 'user_hobbies' on user_hobbies.user_id=user.id
INNER JOIN 'hobbies' on hobbies.id = user_hobbies.hobby_id
WHERE hobbies.name LIKE "query";
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)