New to C#.ne. How to do eager loading if the Foreign Id doesn't match the class name?
I saw this example in the official doc.
var blogs1 = context.Blogs
.Include(b => b.Posts)
.ToList();
I believe under the hood, this one does something like
LEFT OUTER JOIN Post ON Blog.Id = Post.BlogId
In my case, my blog in DB doesn't use id as the primary key, it uses blog_id and the post may use p_id as the primary key and b_id as the foreign key.
How to customize the include with the unconventional key?
You don't need to customize this Entity framework will handle this by Navigation properties (provide a way to navigate an association between two entity type) you have in your model (recommended as they map to foreign keys in the database).
The SQL statement generated from the above LINQ statement may look like this as per your schema:
SELECT * FROM Blog JOIN Post ON Blog.Blog_Id = Post.B_Id
Related
EF 6.1.3 (database first)
.net framework 4.6.1
simple mapping between two tables like the following picture show
here the generated diagram (auto-generated by the wizard)
the statement
Tic_Tickets_new.AsQuerable().Dump() is translated in the following sql query
SELECT
[Extent1].[IdSerie_Ticket] AS [IdSerie_Ticket],
[Extent1].[IdTicket] AS [IdTicket],
[Extent2].[IdNatura] AS [IdNatura]
FROM [dbo].[Tic_Tickets_new] AS [Extent1]
LEFT OUTER JOIN [dbo].[Tic_Tickets_new] AS [Extent2] ON ([Extent2].[ IdNatura] IS NOT NULL) AND ([Extent1].[IdSerie_Ticket] = [Extent2].[IdSerie_Ticket])
AND ([Extent1].[IdTicket] = [Extent2].[IdTicket])
surprise! what is the purpose of the join? It seems totally unusefull
Removing the composite primary key and using in place a single field surrogated key the generate sql statement get simple and smooth without any join
UPDATE
With reference to the comments may be I need to clear the intent of this post; the behavior I explained above is a behavior I already verified on differents projects (database first) when I attempt to load entities partecipating to a * to 0..1 association or 0..1 to 0..1, having a composite primary key and having the associon defined as Independent Association and lazy loading enable; so I consider this as a behavior by design. I already have a workaround and the workaround is to change the type of association from Independent Association to Foreign Key Association.
But the question is WHY?
I'm using database first in EF6, let's say I have a table called Article with (ArticleID, title, text)
with the articleID as the primary key.
Then I add a table called RelatedArticle that has (ArticleID, RelatedArticleID), the primary key is both the articleid and the relatedarticleid with foreign keys back to the article for both.
The problem I'm having is when I pull it into the edmx file it only sets RelatedArticles as a navigation property off of an article so when I go to delete, it only pulls the relatedarticles where the articleid is the article's id I'm trying to delete. Well as you can imagine, I need to be able to say
delete any records where the articleid OR the related articleid is the current article's id that I'm trying to delete.
Or I get big ole FK constraint errors.
Typically when this happens I at least have a "table" off of the context that I can just query manually and kill what I need to. (for example:
context.RelatedArticles.Where(ra => ra.ArticleID == articleID OR
ra.RelatedArticleID == articleID)
But like I said it only pulls in the related articles as a navigational property off of the Article itself.
Ideas?
I have 1:n relationship between to tables in a database: Employee (1) : Role (n)
Role has foreignKey named idEmployee
I want to create a linq statement which will get every role for a given customer. I want to make something like this:
var myQuery = from r in Role
where r.idEmployee == someId
select r;
But, r doesn't have an idEmployee property! How can I get the value of the foreign key?
If you're using EF 4.0 (.NET 4.0), and a database-first programming model with an EDMX model (visual designer), then you need to make sure to have the option Include foreign key columns in the model checked when you add tables to your EDMX model:
If you don't have this option checked, then EF 4.0 will behave the same as EF 1.0/3.5 (in .NET 3.5) which is to include a navigation property - but not the foreign key column as a separate column.
If you are using EF4.0 at least, this will give you what you need: Foreign keys in Entity Framework
If you're using EF1.0, your problem is more serious since it does not show foreign keys in model. You need to iterate through EntityKey.EntityKeyValues collection in search of valid value. But I think this would only get you value of foreign key and would not work in query (since EF would not know how to translate it to SQL query).
But since you have foreign keys, why don't you simply use NavigationProperty to navigate to Employee entity and check value there?
var myQuery = from r in Role
where r.Employee.idEmployee == someId
select r;
Use the include method on Employee class to bring back all the related roles:
var myQuery = from e in Employees.Include(emp => emp.Roles)
where e.EmployeeId == someId
select e
I need to model a friend relationship with Fluent NHibernate. My company model has a List<Company> Related with related companies. Relations between companies are modeled in my database in a table, related which looks like this:
customer_id | related_id
Both columns is a foreign key to the PK in my customers table.
The problem is that relations are only saved once for each pair (do you call it bi-directional?).
I'm able to change the table structure if it's easier to solve in another way.
I need to map Fluent NHibernate so that when i do customer.Related(), it generates a query like:
SELECT * FROM companies LEFT JOIN related ON customer_id = id OR related_id = id
I've tried to map this in a number of different ways, the closest i've tried is:
HasManyToMany(x => x.Related)
.Inverse()
.ParentKeyColumn("customer_id")
.ChildKeyColumn("related_id")
.Table("relations")
.Cascade.All();
However, this (of course) only maps when customer_id matches.
How do I solve this?
Edit:
I think it's similar to Fluent NHibernate: How to create one-to-many bidirectional mapping?, but it does not help me much.
I think what you want to achieve is already half way done. You've mapped 2 entities with a Many2Many relation already. I wouldn't touch mapping any further.
Instead I would query what I want thru that mapping. Something like this.
function GetRelated(long id){
return Session.Query<Related>()
.Where(r=>r.Customer.Id == id || r.Related.Id == id)
.ToList();
}
A reccomendation tho, the mapped entity's name is Related and you have a related field that might sound confusing, so I'd suggest you to rename it into something else (if possible).
Hope it helps.
I'm trying to save an entity that forms part of a many-to-many relationship in the entity framework and am getting the error: Unable to update the EntitySet 'zRM_OP_defaultloccvgsMapping' because it has a DefiningQuery and no element exists in the element to support the current operation.
My google-fu is weak on this one, but I understand I may have to edit the designer code and hook up a stored procedure to manually do the insert.
My table structure looks like this:
locations:
LOCID,
blah..
coverages:
CVGID,
blah..
loccvgs:
LOCID,
CVGID (no keys)
Help!
I have this exact question, but I've come up with a solution. I'll warn you though, it's a really bad one. In my situation I have 3 tables:
Video
- VideoId , int , PK
- blah
Comment
- CommentId, int, PK
- UserId, int (user that made the comment)
- CommentText, string
VideoComments
- VideoId, int, PK
- CommentId, int, PK
First of all, for entity framework to setup the relationship correctly both columns on the association table (VideoComments in my case) must be a primary key.
That said, here is how I am adding a new comment.
public VideoDTO AddCommentToVideo(VideoDTO pVideo, CommentDTO pComment)
{
Video video = context.Videos.Where(v => v.VideoId ==
pVideo.VideoId).FirstOrDefault();
User user = context.Users.Where(u => u.UserId ==
pComment.User.UserId).FirstOrDefault();
Comment comment = new Comment();
comment.CommentText = pComment.CommentText;
comment.User = user;
comment.Videos.Add(video);
context.AddToComments(comment);
context.SaveChanges();
return pVideo;
}
This is very bad...like crossing the streams bad. I do 2 queries to get the full objects mandated by Entity Framework so I can create a new comment. I would like a better way to do this, but I don't know one. Maybe this can help.