Entity Framework Linq query unrelated child tables - c#

I am using Entity Framework 6.1.3 to generated the entities and data model.
If I have two tables: Orders -> OrderDetails, with a relation between them (OrderId), then I can get all the orders and related OrderDetails with the following query
dbContext.Order().Include(a => a.OrderDetails);
But if I created a view (vOrder) for Orders, then there is no direct relation between vOrder and OrderDetails in the model, though I can link them together with joins on OrderId. How could I still get all the data from vOrder and related OrderDetails. The following query doesn't work unless I add all the navigation properties manually.
dbContext.vOrder().Include(a => a.OrderDetails);
Is there a simple LINQ query to accomplish the intended query?
Thanks for your help.

Do a manual join and return an anonymous object that contains both.
Something like:
dbContext.vOrder
.GroupJoin(
dbContext.OrderDetails,
v=>v.orderid,
od=>o.orderid,
(v,od)=>new {v=v,od=od});
Of course, you could just add the appropriate naviation properties on to vOrder and do exactly what you said.

Why not just include more columns in the view (or create another view that has all the required data, if you don't want to modify the first one)?

Related

Get List of Entity Models in DbContext Entity Framework Core 2.1

I'm trying to find a way to get a List of all of the entity models in my DbContext. For instance, if I have two models called Customer and Invoice defined in C# which through code-first I created EF entities and a database, how do I now query the DbContext to get a List that has Customer and Invoice in it -- i.e., all of the entities in that context? I want to be able to call a method that returns a List of all the entities -- not the data, just a list of the entities.
It seems to me this should be so easy, but either it is not easy or I am missing something -- probably the latter. ;-).
Could someone please point me in the right direction? Thanks!!
You can use Model property to get the associated IModel, then GetEntityTypes method to enumerate all IEntityTypes. ClrType property of IEntityType will give you the associated class type, e.g.
DbContext db = ...;
var entityTypes = db.Model.GetEntityTypes().Select(t => t.ClrType).ToList();
IEntityType has many useful properties and (extension) methods for getting information about the primary/alternate keys, foreign keys, navigations, properties etc. in case you need them.
You can refer documetation at: https://learn.microsoft.com/en-us/ef/core/querying/related-data
For ex. If you have blogs and posts as two tables, then you can get related table as shown below. It depends on how the relations are present in the two tables.
You can also add the where clause to get only selected records.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ToList();
}

C#, EF: Map [NotMapped] value from Sql Query

I'm using Entity Framework. I currently have an attribute that is labeled [NotMapped] in my model class. I'm also using a query to bring back that value (from a view, which is why it's not mapped).
var list = context.Database
.SqlQuery<SomeModel>("SELECT NonMappedField, anotherfield FROM SomeView")
.ToList()
Is there a way I can hint to C# that for this instance, it should map the column from the raw query to my models?
I would have more things showing what I've tried, but I don't have the slightest clue of what to do next, other than build my own mapper and that seems like a very brittle solution.
Possible X/Y Problem:
My a data model has a Parent/Child relationship. The Child can be a child of multiple models,necessitating the use of a join table ParentChildJoin. When I do
context.Database.Parent.Where...Include( n => n.Children ).ToList();
I run into query timeouts for a pathetically small number of rows. So I had the bright idea of joining the ParentChildJoin table with the Child table in a View and retrieving the children that way. This works, but I need some way to map the retrieved Child objects to their Parent.
This is where the NotMapped field comes in. I can create a NonMapped field on my model, and then when I retrieve from my View, I can store the ParentId there. From there, I can associate the Child objects with the correct parent.
So that's how I go here.
Either the field is mapped or it isn't, you can't have it both ways!
Take a look at AutoMapper and the AutoMapperEF extension. The EF extension is clever enough to realise that a model that only has a selection of fields from a query will only have those fields in the generated SELECT. You could have several different models for the same query, each only returning the fields required for that model.
What you can do (without changing model) is to concatenate NonMappedField+"_"+anotherfield as anotherfield before load.
After FromSql load, you can split NonMappedField and anotherfield back.
var query = "SELECT [Id], CONVERT(VARCHAR(1024),[NonMappedField]+'|'+[anotherfield]) AS [anotherfield] FROM myView";
var list = _context.SomeModels.FromSql(query)
.Select(i => new SomeModel {
Id = i.Id,
NonMappedField = i.anotherfield.Substring(0, i.anotherfield.IndexOf('|')),
anotherfield = i.anotherfield.Substring(i.anotherfield.IndexOf('|')+1)
}).ToList();

Find entities dependent on other entities (via DB ForeignKeys) in DataContext

I am writing some very generic database code, and I would like to find a way to query a set of types in my entity set (using LINQ to SQL EntityFramework, database-first) which are related to another entity.
So, for example I might have a Product belong to a Category;
SELECT * FROM Products p INNER JOIN Categories c ON p.CategoryId = c.Id
In my database, p.CategoryId is a Foreign Key constrain to be NON-NULL. (i.e; a Product MUST belong to a Category).
Now, if I try to DELETE FROM Categories, I get errors, as there are Products still related to Categories, and I do not have (or want) a CASCADE DELETE applied to the relationship.
What I want to do is examine my DataContext library, and determine dynamically that Categories are key'd by Products, and so if I want to DELETE from Categories, I will first need to DELETE from Products.
By 'dynamically', I mean that my code will not have fore-knowledge of the types or relationships (it does not know about Product or Category entities specifically) but I am willing to use Reflection to assess the DLL to work out these relationships.
I have looked at the DataContext-related code, and can see EntityRef properties on certain Entities (which is half the problem solved), but I can't seem to find any way to tell if these relationships are mandatory or optional (i.e; NON-NULL or NULLABLE) in the underlying database.
?
You know you can automatically cascade deletes in Entity Framework by setting the Delete Rule to "Cascade"? That may make things easier (while not necessarily providing a generic solution for LINQ to SQL).
Take a look here for more info:
http://msdn.microsoft.com/en-us/library/bb738695.aspx

Fluent nHibernate Join

I have an entity that maps to a table called Rule. The table for this entity has an FK to another Table called Category. I'm trying to figure out how to pull in a property from Category in my Rule entity. I'm pretty sure I want to use a join in my entity mapping, but I can't figure out how to configure it so that it works. Here is my mapping:
Join("Category", x =>
{
x.Map(i => i.CategoryName, "Name");
x.KeyColumn("CategoryId");
x.Inverse();
});
Here is the SQL that it's generating...
SELECT ...
FROM Rule rules0_ left outer join Category rules0_1_ on rules0_.Id=rules0_1_.CategoryId
WHERE ...
Here is the SQL that I want.
SELECT ...
FROM Rule rules0_ left outer join Category rules0_1_ on rules0_.CategoryId=rules0_1_.Id
WHERE ...
I can't seem to find anything on the JoinPart that will let me do this. Subselect looks promising from the little bit of documentation I've found, but I can't find any examples of how to use it. Any advice on this problem would be much appreciated. Thanks!
"Join" is poorly named. a "join" in an NHibernate mapping implies a zero-to-one relationship based on a relation of the primary keys of the two tables. You would use a join if, for instance, you had a User table and a UserAdditionalInfo table, with zero or one record per User. The UserAdditionalInfo table would likely reference the PK from User as both a foreign key and its own primary key. This type of thing is common when a DBA has to religiously maintain a schema for a legacy app, but a newer app needs new fields for the same conceptual record.
What you actually need in your situation is a References relationship, where a record has a foreign key relationship to zero or one other records. You'd set it up fluently like so:
References(x=>Category)
.Column("CategoryId")
.Inverse()
.Cascade.None();
The problem with this is that Category must now be mapped; it is a separate entity which is now related to yours. Your options are to live with this model, to "flatten" it by making the entity reference private, changing the mapping to access the entity as such, and coding "pass-throughs" to the properties you want public, or by using a code tool like AutoMapper to project this deep domain model into a flat DTO at runtime for general use. They all have pros and cons.

Eager load a self-referencing table

I have a standard self referencing table of Categories. In my entity model I have made associations Children and Parent. Is it possible to load the whole Category object without lazy loading?
if I use the code below, it loads only to the second level.
db.Categories.MergeOption = System.Data.Objects.MergeOption.NoTracking;
var query = from c in db.Categories.Include("Children")
where c.IsVisible == true
orderby c.SortOrder, c.Id
select c;
Is it possible to load references if I have all the category objects already loaded?
One method to load it is to add the Children property multiple times
db.Categories.Include("Children.Children.Children.Children.Children")
but this generates a very long insane T-SQL code and also it doesn't do what I want.
No, it isn't possible. Consider: All LINQ to Entities queries are translated into SQL. Which SQL statement includes an unlimited depth in a self-referencing hierarchy? In standard SQL, there isn't one. If there's an extension for this in T-SQL, I don't know what it is, and I don't think EF providers do, either.
Ok, you might consider using Load method.
if (!category.Children.IsLoaded)
category.Children.Load();
Of course, category entity need to be tracked by ObjectContext.
There is better explanation here how-does-entity-framework-work-with-recursive-hierarchies-include-seems-not-to.
One way I have used to implement that if I have several entities I want to get all children in self-referencing table is to use recursive cte and stored procedure to get their ids using Entity FrameWork :
Here is the code using Entity Framework and code first approach

Categories

Resources