NHibernate many-to-many inserts null id with hilo generator - asp.net

I have 3 tables: User, Department and UserDepartment. User can be associated with multiple departments and department can be associated with multiple users. I use many-to-many fluent mapping on both sides like this:
For Department
HasManyToMany(x => x.Users)
.Table("UserDepartment")
.ParentKeyColumn("DepartmentId")
.ChildKeyColumn("UserId")
.AsSet()
.Cascade.All();
For User
HasManyToMany(x => x.Departments)
.Table("UserDepartment")
.ParentKeyColumn("UserId")
.ChildKeyColumn("DepartmentId")
.AsBag()
.Inverse()
.Cascade.None();
All tables use HiLo Id generator and almost similar mapping, like this:
Id(p => p.Id).GeneratedBy.HiLo("HiLo", "NextHi", "32", "ForTable = 'UserDepartment'");
When I try to add some users to department nhiberante fails with an error:
could not execute batch command.[SQL: SQL not available]. And inner
exception: Cannot insert the value NULL into column 'Id', table
'test.dbo.UserDepartment'; column does not allow nulls. INSERT
fails.\r\nThe statement has been terminated.
I have the same HiLo generator working with other tables, so I'm pretty sure it doesn't cause this failure.
Can someone shed some light on this problem? I can recall having problem with null Id insert in the past and it was solved by using inverse mapping on collection, but I cannot use inverse on both sides, so I need another solution.

Finally I have found the solution. There are two ways:
Remove synthetic ID from table and use composite ID instead.
Use XML mapping to specify idbag behaviour.
as expained in: NHibernate, HiLo and many-to-many association

Related

Force 'fetch joined' relations to include IDENTITY of their ManyToOne relations using HYDRATE_ARRAY?

I have a query in which I'm joining a number of tables to my original Person entity. A Person may have multiple Child relations (OneToMany), and a Child may have a School they go to (ManyToOne). Problem is, I don't need the entire School entity that connects to each child, only their id, which is already stored on Child.
I'm using a Paginator to iterate through the results and I use HYDRATE_ARRAY to reduce overhead of the ORM parsing data to entity objects. But the id fields of unfetched relations are not returned this way, and thus, the School id isn't either.
I may join the School entity too, but since the identity is already stored on the Child records, I don't see why I should further reduce performance by having the database join another table. Fetching results as entity objects would also solve the problem, but also at the cost of performance. How can I get the id to apper the results without having to unnecessarily join the the School entity or having to hydrate the results as objects?
$query = $em->getRepository(Entity\Person::class)->createQueryBuilder('p');
$query
->select([
'p as person',
'w.name as workplace_name',
'c',
])
->leftJoin('p.children', 'c') //Entity\Child
->leftJoin('p.workplace', 'w') //Entity\Company
//...
;
$paginator = new Paginator($query);
$paginator->getQuery()
->setHydrationMode(\Doctrine\ORM\Query::HYDRATE_ARRAY);
You can use Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS to include the foreign key column values in the result:
$paginator->getQuery()
->setHint(\Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS, true)
->setHydrationMode(\Doctrine\ORM\Query::HYDRATE_ARRAY);
which:
The includeMetaColumns query hint causes meta columns like foreign keys and discriminator columns to be selected and returned as part of the query result.
Reference
Doctrine\ORM\Query documentation
How to get association foreign key IDs in Doctrine 2 without loading the associated object?
Getting only ID from entity relations without fetching whole object in Doctrine

Invalid Column Name : SQL / ASP.NET

I'm having a hard time debugging a particular problem and have a couple questions. First, here is what's going on:
I have a relatively simple table called Employees, which has a primary key / identity Id. There is also a Username column - which is a GUID foreign key to my aspnet_Users table used for membership. Finally, there is another foreign key Team_Id which points to another table, Teams.
All I'm really trying to do is give a selected employee's Id and pass it to a method in the DAL which then finds the employee with the following statement:
var employee = entities.Employees.Where(emp => emp.Id == employeeId);
Once the employee is retrieved, I want to use another value which is passed to the same method - the selected team's Id - to update the employee's Team_Id value (which team they are assigned to), using the following:
employee.First().Team_Id = teamId;
entities.SaveChanges();
I get the exception
Invalid column name: {Name}
which doesn't make sense to me, because Employee doesn't have a name column.
All of that said, my questions are:
Where could the mix up possibly be coming from? I've tried thinking up a way to step through the code, but it seems like the error is somewhere in the query itself so I'm not really sure how to trace the execution of the query itself.
Is it possible that it may have something to do with my generated Entities? I noticed that when I type employee.First(). Name comes up in Intellisense. I'm really confused by that, since as I've mentioned there is no Name column in the employees table.
Fixed the issue. I just removed the existing Entity Framework Model and re-added it.
As far as the query goes, you can always use SQL Profiler to watch what scripts are actually running. That's a good way to troubleshoot generated SQL anyway.
For your property, somehow that did make it to your class, so your data model thinks it's there, for whatever reason. I'd say just go to your data model (you don't mention if this this is EF or LINQ-to-SQL), and you'll see "Name" there. Just remove it, and it will remove it from the class, and from the data access stuff.

Linq query returning Less records than Sql Query

I am facing a big problem with simple linq query.. I am using EF 4.0..
I am trying to take all the records from a table using a linq query:
var result = context.tablename.select(x=>x);
This results in less rows than the normal sql query which is select * from tablename;
This table has more than 5 tables as child objects (foreign key relations: one to one and one to many etc)..
This result variable after executing that linq statement returns records with all child object values without doing a include statement..
I don't know is it a default behavior of EF 4.0 ..
I tried this statement in linqpad also..but there is no use...
But interesting thing is if I do a join on the same table with another one table is working same is sql inner join and count is same..but I don't know why is it acting differently with that table only..
Is it doing inner joins with all child tables before returning the all records of that parent table??
please help me..
This table has more than 5 tables as
child objects (foreign key relations:
one to one and one to many etc)..
This result variable after executing
that linq statement returns records
with all child object values without
doing a include statement..
So we are probably talking about database view or custom DefiningQuery in SSDL.
I described the same behavior here. Your entity based on joined tables probably doesn't have unique identification for each retruned row so your problem is Identity map. You must manually configure entity key of your entity. It should be composite key based on all primary keys from joined tables. Entity key is used to identify entity in indenty map. If you don't have unique key for each record only first record with the new key is used. If you didn't specify the key manually EF had infered its own.
The easiest way to troubleshoot these types of issues is to look at the generated SQL produced by the ORM tool.
If you are using SQL Server then using the SQL Profiler to view the generated SQL.
From what you are describing, a possible explanation might be that your relationships between entities are mandatory and thereby enforcing INNER joins instead of LEFT OUTER joins.

insert data from a asp.net form to a sql database with foreign key constraints

i have two tables
asset employee
assetid-pk empid-pk
empid-fk
now, i have a form to populate the asset table but it cant because of the foreign key constraint..
what to do?
thx
Tk
Foreign keys are created for a good reason - to prevent orphan rows at a minimum. Create the corresponding parent and then use the appropriate value as the foreign key value on the child table.
You should think about this update as a series of SQL statements, not just one statement. You'll process the statements in order of dependency, see example.
Asset
PK AssetID
AssetName
FK EmployeeID
etc...
Employee
PK EmployeeID
EmployeeName
etc...
If you want to "add" a new asset, you'll first need to know which employee it will be assigned to. If it will be assigned to a new employee, you'll need to add them first.
Here is an example of adding a asset named 'BOOK' for a new employee named 'Zach'.
DECLARE #EmployeeFK AS INT;
INSERT (EmployeeName) VALUES ('Zach') INTO EMPLOYEE;
SELECT #EmployeeFK = ##IDENTITY;
INSERT (AssetName, EmployeeID) VALUES ('BOOK',#EmployeeFK) INTO ASSET;
The important thing to notice above, is that we grab the new identity (aka: EmployeeID) assigned to 'Zach', so we can use it when we add the new asset.
If I understand you correctly, are you trying to build the data graph locally before persisting to the data? That is, create the parent and child records within the application and persist it all at once?
There are a couple approaches to this. One approach people take is to use GUIDs as the unique identifiers for the data. That way you don't need to get the next ID from the database, you can just create the graph locally and persist the whole thing. There's been a debate on this approach between software and database for a long time, because while it makes a lot of sense in many ways (hit the database less often, maintain relationships before persisting, uniquely identify data across systems) it turns out to be a significant resource hit on the database.
Another approach is to use an ORM that will handle the persistence mapping for you. Something like NHibernate, for example. You would create your parent object and the child objects would just be properties on that. They wouldn't have any concept of foreign keys and IDs and such, they'd just be objects in code related by being set as properties on each other (such as a "blog post" object with a generic collection of "comment" objects, etc.). This graph would be handed off to the ORM which would use its knowledge of the mapping between the objects and the persistence to send it off to the database in the correct order, perhaps giving back the same object but with ID numbers populated.
Or is this not what you're asking? It's a little unclear, to be honest.

Inserting an [Order] and [OrderItems] in LINQ

I'm quite new to LINQ and was wondering what was the best design for inserting an [Order], subsequently getting the [Order].[ID] and using this to save some [OrderItems].
The ID column of the [Order] table is an Identity column.
I want to try and prevent calling db.SubmitChanges(), getting the newly inserted Order ID and then having to call it (db.SubmitChanges()) again when inserting the related Order Items - is this the only way to do this though?
Thanks in advance.
If you have your LINQ to SQL Classes set up correctly, then Order should have a collection of OrderItems.
You should be able to create an Order and then add new OrderItems to the collection and then call db.SubmitChanges() once and allow LINQ to SQL handle the Id issues.
You don't have to call it in two separate steps. LINQ takes care of that for you.
If you have your database modeled correctly using a foreign key relationship between your Order and OrderItems tables, then the generated objects will also have a relationship. They Order will be composed with OrderItems. Specifically in the case of a one-to-many relationship, your Order object will have a property OrderItems that will be a collection of OrderItem objects.
LINQ is smart enough to see the composition of your objects, and because it has knowledge of the type of constraint between your tables, if will insert all the records in the correct order with the appropriate IDs, to create the same entity modeled in your OOP code, in the relational world.
So, you only have to call SubmitChanges once.
db.Orders.InsertOnSubmit(myOrder);
db.SubmitChanges();

Resources