Fluent NHibernate join not using primary key - c#

I am trying to get a single property from a joined table where a non-PK in my main table is joined to the PK of the foreign table. Below is an oversimplified example of what I am trying to accomplish (I do not want to reference the foreign entity):
Tables:
CREATE TABLE Status
(
Id int,
Body text,
CategoryId int
)
CREATE TABLE Category
(
Id int,
Name text
)
SQL to generate:
SELECT Id, Body, CategoryId, Category.Name AS CategoryName
FROM Status
LEFT JOIN Category ON Category.Id = Status.CategoryId
I am trying to map the join like this in the StatusMap but it seems to be joining on the two primary keys (where Status.Id = Category.Id):
Join("Category" m =>
{
m.Optional();
m.KeyColumn("CategoryId");
m.Map(x => x.CategoryName, "Name");
});

As far as I know the only way around this using Fluent is to map to a view as you currently are doing. Join() will always map to the primary key of the parent table. The KeyColumn method specifies the key column for the child table only, which in your case is the Category table.
To achieve the desired SQL using your simplified version above you'd probably want to use References to define a many-to-one relationship between status and category.

Related

ADO Entity Builder won't generate class for table with just foreign keys

I have a SQL table that has two foreign keys and when I run Entity Data Model Wizard and select Code First from database, and then create the tables, my table won't show up as a class. It generates something in the primary model class that looks like this:
modelBuilder.Entity<User>()
.HasMany(e => e.Categories)
.WithMany(e => e.Users)
.Map(m => m.ToTable("UserCategory").MapLeftKey("UserID").MapRightKey("ID"));
But I don't know how to use that to add or delete from that table, since it won't show up as a class when I'm coding.
My tables are:
CREATE TABLE [User]
(
ID NVARCHAR(128) PRIMARY KEY,
FirstName VARCHAR(255) NOT NULL,
LastName VARCHAR(255),
JoinDate DATETIME,
ZipCode VARCHAR(25),
SearchRadius INT,
LoginToBusinessSide BIT
);
/*The categories businesses can fall under. */
CREATE TABLE Category
(
ID INT IDENTITY(1,1) PRIMARY KEY,
[Name] VARCHAR(255) UNIQUE NOT NULL,
);
/*The categories chosen by a specific user to get notified of*/
CREATE TABLE UserCategory
(
ID INT FOREIGN KEY REFERENCES Category(ID),
UserID NVARCHAR(128) FOREIGN KEY REFERENCES [User](ID),
CONSTRAINT PK_UserCategory PRIMARY KEY (ID, UserID)
);
How do I get UserCategory to show up as its own class, so I can easily access it?
I want to be able to just access it like every other class:
db.UserCategories.ID =
How can I
ADO doesn't create a class for my many to many table, but I can still access it. To add new categories to it, I use this code:
for(var i = 0; i < categories.Length; ++i)
{
var user = db.Users.Find(thisUser.ID);
var cat = db.Categories.Find(categories[i]);
user.Categories.Add(cat);
}
I have to an active connection to both tables that the foreign keys are linked to, and then when I add one to the Categories table, it goes to the correct place.
If you understand exactly why this works, or if there's a better way, please do comment.

Join two tables in nhibernate mvc c#

I am joining two tables using primary key and foreign key.
My tables are
Item, Columns are:
ItemId int primary key,
Name varchar,
Price float,
CategoryID int foreign key,
QtyInStock int
Category, Columns are:
Id int pk,
Category varchar,
Name varchar
I want to select Category on basis of ID=categoryId
I am using NHibernate 4.03 with xml configuration files.
For unrelated entities:
var query = from item in session.Query<Item>()
join category in session.Query<Category>() on item.CategoryID equals category.Id;
For related entities:
Category catAlias = null;
var query = session.QueryOver<Item>()
.JoinAlias(x => x.Category, () => catAlias);

Joining tables in Entity Framework

I have a table called Students and a table called Majors, Students and Majors are joined by MajorId I have set this relationship already and have set the foreign key in the schema. When I access my Student object how can I return the MajorName column (this comes from the Majors table)? The only options I have in intellisense is Major_1, Major_1Reference, MajorId .
Major_1 should be a navigation property leading to the appropriate Major entry, so you should be able to access the Major's properties like this:
from s in ctx.Students
select s.Major_1.MajorName
You can use linq join statement like this to make query on the two tables...
var q = from s in Students
join m in Majors on s.MajorId equals m.MajorId
select new { m.MajorName };

How to check if a column is already a foreign key?

I have table named Person and column named ID
how to check if ID is already FOREIGN KEY cause I want to make it with this code:
ALTER TABLE Person ADD FOREIGN KEY(ID) REFERENCES Job(ID)
ON DELETE CASCADE ON UPDATE CASCADE
but if ID is already a FOREIGN KEY it gives me the following error "may cause cycles or multiple cascade paths" because of the condition with two cascades... How to check if this field is FOREIGN KEY to avoid this error?
You'd want to look in the INFORMATION SCHEMA views
Though it's not as complete as it should be. This is the final query you'd want:
SELECT
KCU1.CONSTRAINT_NAME AS 'FK_CONSTRAINT_NAME'
, KCU1.TABLE_NAME AS 'FK_TABLE_NAME'
, KCU1.COLUMN_NAME AS 'FK_COLUMN_NAME'
, KCU1.ORDINAL_POSITION AS 'FK_ORDINAL_POSITION'
, KCU2.CONSTRAINT_NAME AS 'UQ_CONSTRAINT_NAME'
, KCU2.TABLE_NAME AS 'UQ_TABLE_NAME'
, KCU2.COLUMN_NAME AS 'UQ_COLUMN_NAME'
, KCU2.ORDINAL_POSITION AS 'UQ_ORDINAL_POSITION'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1
ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2
ON KCU2.CONSTRAINT_CATALOG =
RC.UNIQUE_CONSTRAINT_CATALOG
AND KCU2.CONSTRAINT_SCHEMA =
RC.UNIQUE_CONSTRAINT_SCHEMA
AND KCU2.CONSTRAINT_NAME =
RC.UNIQUE_CONSTRAINT_NAME
AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION
See here for more information
http://msdn.microsoft.com/en-us/library/aa175805(v=sql.80).aspx
Here is a simple little version
SELECT TOP(1) a.COLUMN_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS b JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE a ON a.CONSTRAINT_CATALOG = b.CONSTRAINT_CATALOG AND a.CONSTRAINT_NAME = b.CONSTRAINT_NAME WHERE a.COLUMN_NAME = *your column*)
You can easily add table name and DB name in the where clause as well

LINQ to SQL - Delete Many to Many if no relations

I have a table that store "Tags" like so:
ProductTags
TagID PK
Name nvarchar(50) [not null]
and a M2M map table like this:
ProductTagMap
ProductID PK
TagID PK
Now let's say I remove a tag relationship (or all of them) from a Product like so:
// get our Product we are working on...
Product product = dataContext.Products.Where(p > p.ProductID = 1);
// this remove the link between the product and its tags
dataContext.ProductTagMaps.DeleteAllOnSubmit(product.ProductTagMaps);
//*** If these product-specific Tag/s is/are no longer used ***/
//*** by any other Products I'd like to delete them ***/
//*** How can this be done here? ***/
dataContext.SubmitChanges();
If these Tags (that were/are related to the specific product) are no longer related to any Products I'd like them to be deleted.
How can this be done in the code above (see the comment)?
Since that would require checking for other mappings in other records, you'd have to do a query to check for orphans:
var tags = from t in dataContext.Tags
where t.ProductTags.Count() == 0
select t;
dataContext.Tags.DeleteAllOnSubmit(tags);
And this gives you the tags you can delete.

Categories

Resources