NHibernate - Exclude subclass using Criteria with Joined Subclass - asp.net

I have a fluent nhibernate configuration in my app. Running latest of both. I am trying to create a criteria statement to pull back a specific class in a joined subclass hierarchy. This is an example of my inheritance structure:
Admin is an Employee is a Person (Admin : Employee, Employee : Person)
What I am trying to get is the Employees but not the Admins, but since admins are employees, they are coming back in the query. I do not have a discriminator column to use. Is there any way to accomplish this using the Criteria API?
Thanks in advance.
Schema as requested (just an example):
Person table: Id, Name
Employee table: PersonId, EmployeeNumber
Admin: PersonId, AdminNumber
NHibernate relates those properly. Everything else works except this specific type of query.

It appears that Criteria does not support that functionality. I was able to solve the issue by adding a SQL Restriction to the query to filter out the subclass results.
criteria.Add(
Expression.SQL("{alias}.MyPrimaryKey NOT IN (SELECT MyPrimaryKey FROM Admin)"));
This essentially excludes and results from the Employee SQL query where that Employee exists in the Admin table, thus returning only Employees that are not Admins.
I originally tried separately querying the Admin table via Criteria to get a list of Ids which I then fed into the Employee query using a NOT IN Criteria statement Restrictions.Not(Restrictions.In()) but SQL Server restricts the number of parameters to 2100 and blows up if that collection of Ids that you are trying to exclude has more than 2100 items.

Related

What's the best way to store users in DynamoDB so I can get one efficiently, and a related group as well?

I have users for my website that need to log in. In order to do that, I have to check the database for them, by email address or a hash of their email.
Some of my users have an online course in common.
Others are all on the same project.
There are multiple projects and courses.
How might I set up my table so that I can grab individual users, and efficiently query related groups of users?
I'm thinking...
PK = user#mysite
SK = user#email.com
projects = [1,2,3]
courses = [101,202,303]
I can get any user user with a get PK = user#mysite, SK = user#email.com.
But if I query, I have to filter two attributes, and I feel like I'm no longer very efficient.
If I set up users like this on the other hand:
PK = user#email.com
SK = 1#2#3#101#202#303
projects = [1,2,3]
courses = [101,202,303]
Then I can get PK = user#gmail.com and that's unique on its own.
And I can query SK contains 101 for example if I want all the 101 course students.
But I have to maintain this weird # deliminated list of things in the SK string.
Am I thinking about this the right way?
You want to find items which possess a value in an attribute holding a list of values. So do I sometimes! But there is not an index for that.
You can, however, solve this by adding new items to the table.
Your main item would have the email address as both the PK and the SK. It includes attributes listing the courses and projects, and all the other metadata about that user.
For each course, you insert additional items where the course id is the PK and the member emails are the various SKs in that item collection. Same for projects.
Given an email, you can find all about them with a get item. Given a course or project you can find all matching emails with a query against the course or project id. Do a batch get items then if you need all the data about each email.
When someone adds or drops a course or project, you update the main item as well as add/remove the additional indexed items.
Should you want to query by course X and project Y you can pull the matching results to the client and join in the client on email address.
In one of your designs you're proposing a contains against the SK, which is not a supported operator against SKs so that design wouldn't work.

Asp.net Multi Tenancy implementation on existing solution

I have an asp.net MVC solution, Entity Framework code first, which has dozens of database tables all designed around a single company using the solution.
The requirement has come up to allow multiple companies to use the solution, so what we have done is add "CompanyID" as a column to all database tables and set a default value. There is a company table with the various company names and CompanyID's. On login the user selects the company they are logging in as which stores the CompanyID in the session.
At the moment every Entity Framework call now has to be updated to include the CompanyID, for example when selecting Employees I am doing:
List<Employee> employees = db.Employees.Where(x => x.CompanyID = Session.CompanyID).ToList();
As you can see it will be tedious to do this on thousands of calls to the db. Any update, save, and fetch has to change.
Surely I am doing it the long way and there is a way at runtime, globally to append all DB calls to include the CompanyID stored in the logged in users Session? Something that dynamically appends the CompanyID when fetching values or storing etc? Perhaps a package I can use to do this task at runtime?
In my opinion, there is no need to add CompanyID to EVERY table in the database. I would select just "root" tables/entities for that. For example, Employee or Department clearly sounds like a many-to-one relationship with a company - so adding CompanyID there sounds right. But, for example, EmployeeEquipment which is a many-to-one relationship with Employee does not have to have CompanyID column since it can be filtered by the joined Employee table.
Regarding your request to filter by CompanyID globally, I'm not aware of anything that can do that per request. There are global filters for Entity Framework, but I'm not sure how you can apply them per-request. Take a look on .HasQueryFilter() during model creation if you are using Entity Framework Core.

Challenges with adding a 1-1 relational table (Users and UserSettings)

My issue is related to this question: Entity Framework One-To-One Mapping Issues
I have a Users table that already has a bunch of records.
Users (Id, UserName, Password, FullName, Gender)
I need to add a bunch of notification options for each user:
NotifyForNewComment
NotifyForNewPost
NotifyWhenFriendSignsUp
I may have to add more options later, but there will always be a 1-1 relationship, so my question is whether to store these in a separate table, say UserSettings, or just add them as columns to the Users table.
In the linked question (above), the advice was to create a new table and make the UserId in the UserSettings table as the primary key (because otherwise, Entity Framework doesn't like it). If that's what I have to do, then I have a few questions regarding it:
All my tables have an Id column. The UserSettings will not have an Id column then, since the UserId will be the primary key?
I'd have to turn on Identity Insert for the UserSettings table, so that when I insert a new User record, I can also insert a UserSettings record with the UserId?
Given that I already have a bunch of records in the Users table, what do I have to do if I'm going to introduce the new UserSettings table now which will have a 1-1 relationship with the Users table? Do I just run a script to add records for each user in the Users table with some default values? Or do I make it into a 0-1 relationship?
Since it's a 1-1 relationship, should I not worry about a new table, and instead just add them as columns to the existing Users table?
I think you are missing the point of a UserSettings table. It would have columns like:
UserSettingsId
UserId
Notification
It might also contain things like when the notification was created, whether it is currently enabled, and other information.
If you know exactly what the notifications are, and they are not going to change, then you might consider adding them as separate columns in the user table.
On the other hand, this is a natural 1-N relationship, and you should probably implement it as such.

How to share table property between two tables in ADO Entity Data?

i'm having a little problem in my project. i'm using ADO.Net Entity Data Model,
let's say i have 2 Tables:
Offices : a. id
b. Name
Requests: a. rid
b.fname
c.lname
d.mobile
i want the requests table will have a relations to the offices table that each row in requests will have the id of the one of the tables.
i tried to do 1 to many relations but it didn't work , i just couldnt add data to the table.
thanks for your guidence
Your Requests table needs to have a field to relate back to the offices table. Which typically should be named OfficeID or something similar. Add that field and create the relationship from Offices.ID to Requests.OfficeID and it will work fine.

asp.net MVC fetching data with table relations

I have created my Database which has:
Artist, tracks and TracksPerArtists
I can do sql queries through the entity model. For example when I make:
database.TRACK.ToList()
I get the list of track to be shown on index view for example. But my foreign keys come empty. While there is an artist and a track, and the correct row for ArtistsPerTrack, this item in my track.ToList() collection is empty.
Is there a different way to fetch those data?
I came from cakePHP framework in which you can define the Model.recursive property to declare the depth of the relations you want to fetch.
Is there anything similar here?
There is something similar.
If "database" is DataContext and Artist and Tracks have many to many relationship in database, you can fetch related entities using Include clause:
database.TRACK.Include("Artists").ToList()
where "Artists" is the name of property on Track entity.

Resources