EF Core Navigation property not loaded even after using include - ef-core-2.0

Here is my db design
For this I am retrieving the data through following query in EF Core.
from u in _context.Users
from r in _context.Roles.Include("RoleApplicationActivity")
from raa in _context.RoleAppActivities.Include("Application").Include("Activity").Include("Role")
from app in _context.Applications.Include(a => a.RoleApplicationActivity)
from ac in _context.Activities.Include(a => a.RoleApplicationActivity)
where u.Id == id
select new FullUser
{
User = u,
Roles = u.Roles,
RoleAppActivity = r.RoleApplicationActivity
}
Even after using includes when i check the values for navigation property they are empty. wondering what I am missing. Help appreciated.
Before I run this query if load all the required entities then EF Core is populating the data for me. Wondering if it is good way to do it.
_context.Applications.Load();
_context.Roles.Load();
_context.Activities.Load();

Related

MVC accessing linked table value using entity framework

I am new to entity framework and I am trying to get my head around it. I am used to writing stored procedures which have all the data I need on a example by example basis.
I am under the impression that I can get all values from a particular table including the foreign key values direct using entity framework without having to write a select query which joins the data.
I have the following in my controller
public ActionResult Patient()
{
using (var context = new WaysToWellnessDB())
{
var patients = context.Patients.ToList();
return View(patients);
}
}
In my view I have the following
#foreach (var item in Model)
{
<p>
#item.FirstName #item.Surname #item.Gender.GenderDesc
</p>
}
I have two tables, Patient and Gender, GenderId is a foreign key which I am trying to get the GenderDesc from that table.
I am getting the following message
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Can someone explain why I cannot access GenderDesc. It does work if I remove the using() around my context, but I don't really want to leave that open, is there a way to get this to work still having the using around?
Thanks in advance.
Correct, you have disposed of the context as it is within a using statement, so anything you try to access from then on will not be able to be lazy loaded. The disadvantage with lazy loading is that it will perform a query for the gender for every patient you are iterating over, which is handy, but bad! I would load the related table at query time using Include.
You'll need a new import:
using System.Data.Entity;
And then include the related table:
var patients = context.Patients.Include(p => p.Gender).ToList();
That will result in a query which will join to your "Gender" table and you should be able to output item.Gender.GenderDesc in your view.

Joining tables from two databases using entity framework

I am working on an ASP.NET MVC 4 web application. I am using Entity Framework as the data access layer, using database first approach (.edmx file).
Currently I have a problem in join tables that are defined inside two different databases (i.e. I have two .edmx files).
For example if I want to join tables I am performing the following query:-
public ActionResult AutoComplete(string term)
{
var tech = repository.AllFindTechnolog(term).Take(100);//Call to the first database
var resources = repository.GetResources(tech.Select(a => a.IT360ID.Value).ToArray(), false);//call to the second database
var query = from techItems in tech
join resourcesItems in resources
on techItems.IT360ID.Value equals resourcesItems.RESOURCEID // join based on db2ID
orderby techItems.PartialTag
select new //code goes here
return Json(query, JsonRequestBehavior.AllowGet);
}
I will have two separate calls to the database, and a join inside the application server, which is not the best performance-oriented solution. Ideally the joins will happen completely inside the database engine.
I know that a stored procedure will allow me to join tables from different databases purely on the server, but I do not want to use SP because it will make my code less maintainable and less testable.
So I am searching for a solution where I can do the join using entity framework and to result in a single database join?
If you want to do it with a single database call you will have to create a View in the database that joins the 2 tables from separate db's. Once the view is created you can add it to EF as a single object, which you can manipulate further and Query off of. The view will basically be a table and it will be easily maintable and easy to bind to a strongly typed model
Another way ,similiar like you have posted, you can query separate .edmx files and then join them.
Yes, there is 2 calls to the database but it shouldn't be that expensive and probably won't notice a difference.
using(var db = new MyEntities())
using (var db2 = new MyEntities2())
{
var one = db.Table1.AsEnumerable();
var two = db2.Table2.AsEnumerable();
var result = from o in one
join t in two on o.Id equals t.Id
// blah blah
}
#CSharper's answer is close. As #Oliver mentioned in the comments, IEnumerable loads the table into application memory, leading to crashes if you have a large database.
The solution is to use IQueryable, which can be called with LINQ - this produces SQL which is much faster.
// This is a generic method, modify to your needs
public ActionResult Details(int? id)
var one = db.Table1.AsQueryable();
var two = db2.Table2.AsQueryable();
// since you're using MVC EF, I assume you want to put this in a viewmodel
// (in this case ObjectCombined)
// assume "id" is passed as parameter
Object1 result1 = (from o in one where one.id == id select o).Single();
Object2 result2 = (from t in two where t.id == o.id select t).Single();
ObjectCombined result = new ObjectCombined(result1, result2);
return View(result);
}
Might I suggest that you look into using a synonym in your database. For instance, you can create a synonym to the resources table in the database that your tech table is located. This will ensure that you will not need to maintain 2 EDMX files. Instead you can have a single EDMX file and you can simply join your tech table to the synonym of the resource table and voila - you are on your way.
UPDATE: Please note that if you are using synonyms there is an extra bit of work you will need to do to the EDMX file to get it working in Entity Framework. Here is a blog post that was put out by a programmer who got it to work. Here is the original stackoverflow question she asked.
HAPPY CODING!!! :)
you can create a view or a stored procedure, your sql statement can then make cross db query just make sure your credentials can DML or DDL on both db. otherwise try the nested using entities that will make sure you will not get the linq bug when you dont declare the db entity inside a using statement.

Error in breeze using EF 5 and calling stored procedure

Getting an error client side with breeze: "Cannot call method 'map' of undefined" when trying to pull over some data. The difference between this action and one that works is that this action is calling a stored procedure and returning ObjectResult<T> instead of DbSet<T>.
Might this be why I get an error? Using Chrome Developer tools, I do see that the breeze controller is returning json data.
I have created a complex model type in the edmx for mapping the rows returned from the stored procedure.
The action in the breeze controller has a return type of IEnumerable<T>.
I experienced the same error when using an EF complex type. A workaround was to create a view in my database instead of using a complex type, set the stored procedure to return a type of the new view which had a primary key and then it worked. It would seem that breeze requires entities to have a primary key defined.
Hm... not quite sure what is happening, so just guessing here, but try adding an AsQueryable() to the result returned, and changing the result type to a IQueryable.
We don't have any stored proc tests for breeze yet, but this is impetus for me to add some :)
I had the very same issue, but thank God I figured out a solution. Instead of using a stored procedure, you should use a view, as Breeze recognizes views as DbSet<T>, just like tables. Say you have a SQL server table that contains two tables Customers and Orders.
Customers (**CustomerId**, FirstName, LastName)
Orders (OrderId, #CustomerId, OrderDate, OrderTotal)
Now, say you want a query that returns orders by CustomerId. Usually, you would do that in a stored procedure, but as I said, you need to use a view instead. So the query will look like this in the view.
Select o.OrderId, c.CustomerId, o.OrderDate, o.OrderTotal
from dbo.Orders o inner join dbo.Customers c on c.CustomerId = o.CustomerId
Notice there is no filtering (where ...). So:
i. Create a [general] view that includes the filtering key(s) and name it, say, OrdersByCustomers
ii. Add the OrdersByCustomers view to the entity model in your VS project
iii. Add the entity to the Breeze controller, as such:
public IQueryable<OrdersByCustomers> OrdersByCustomerId(int id)
{
return _contextProvider.Context.OrdersByCustomers
.Where(r => r.CustomerId == id);
}
Notice the .Where(r => r.CustomerId == id) filter. We could do it in the data service file, but because we want the user to see only his personal data, we need to filter from the server so it only returns his data.
iv. Now, that the entity is set in the controller, you may invoke it in the data service file, as such:
var getOrdersByCustomerId = function(orderObservable, id)
{
var query = breeze.EntityQuery.from('OrdersByCustomerId')
.WithParameters({ CustomerId: id });
return manager.executeQuery(query)
.then(function(data) {
if (orderObservable) orderObservable(data.results);
}
.fail(function(e) {
logError('Retrieve Data Failed');
}
}
v. You probably know what to do next from here.
Hope it helps.

MVC and Entity Framework Key

I am new to MVC and EF and am having a heck of a time getting an EF query to work, specifically with the EF key="". After adding some test code, the error being returned here is 'The name idAddress does not exist in the current context'. There is a primary key on the Address table named idAddress - identty int
I have read through many suggestions on the site and can't get past this.
private motion_care_360Entities db = new motion_care_360Entities();
public ActionResult GetItems(GridParams g)
{
var list = db.Addresses.Include("AddressCountry").Include("AddressState").Include("AddressType").AsQueryable();
var list1 = list.OrderBy(o => idAddress).ToList();
var l1 = list1[0].AddressState.State;
return Json(new GridModelBuilder<Address>(list, g)
{
Key = "idAddress", // needed when using Entity Framework, usually it's Id
// If you're using EF, it's needed so that the data will be ordered by it before paging it
Map = o => new
{
AddressTypeType = o.AddressType.Type,
AddressStateState = o.AddressState.State,
AddressCountryCountry = o.AddressCountry.Country,
o.City,
}
}.Build());
}
}
That would need to be list.OrderBy(o => o.idAddress).ToList();
You need to specify that it's by the idAddress of the object (i.e. o from your lambda expression) itself.
You're actually confused about a lot of things. First, the issue you claim you have has nothing to do with either MVC or EF. It has to do with whatever GridModelBuilder is, and since that's not a part of MVC, you must be using some third party control for that.
Second, I'm guessing (since I don't know what third party control you're using) that Key is used when using GroupBy, not when using OrderBy. OrderBy does not have a key, but GroupBy does. But it's hard to know, since you seem to think that third party tools are part of the framework.
Third, your OrderBy is assigned to list1, which you never use. You use list, which is unordered.
Fourth, you don't need AsQueryable as it's already a Queryable.

linq mvc foreign key value

I am new to MVC. and I'm trying to find my way through online tutorials.
being said that,
I have a table A (a1,a2,a_b1)
and a table B (b1,b2)
and a_b1 is a foreign key from B.b1.
I generated the List view in Visual studio, using its template.
I have access to a1, and a2 fields of table A.
<%=Html.Encode(item.a1) %> and <%=Html.Encode(item.a2) %>
but when I try to access the A.a_b1 value (NOT the reference to table B), I only get the reference to an object from table B.
Thanks Kirill
I don't know what are CodeFirst, ModelFirst or DatabaseFirst.
I have these tables, and used visual studio, and Linq to generate the class for tables A and B.
so A.a1, A.a2 show up in the object created.
and I have A.B, and A.BReference in the fields
I think there should be a way to access the value of the column not the reference.
Can you please help me?
I don't want to perform the join, just need the value.
I tried my best to be specific but please let me know if this is not clear.
Thanks
EDIT:
I used ADO.Net Entity Data Model to generate objects associated with my tables.
In my controller I have :
A sample1=repository.search(id);
string s1 = sample1.a1;
string s2 = sample1.a2;
string s3 = sample1.a_b1; (ERROR)
Instead I have
sample1.B (an object of type B)
and
sample1.BReference (object of type EntityReference<B>)
Answer for those who ran into the same problem:
I defined a new class A_text that has all the fields of A. (including a_b1)
and in Select, I used :
var result = from pt in db.A
where pt.id== id
select new A_text
{
id= pt.id,
a1= pt.a1,
a2 = pt.a2,
a_b1= pt.a_b1.id
};
return (result.FirstOrDefault());
I'm not sure about the efficiency compared to the
db.Search(id);
but seems ok so far.

Resources