How to query a list in LINQ - asp.net-mvc

I have 2 tables in my database, one for projects members and one for projects
After authenticating the user I have his ID. In my project members table I have the project ID and the user ID.
I can obtain a list of project members for this user using
var pm = db.ProjectMembers.Where(c=> c.UserID=u.UserID) ;
Now my question is how can I get a list of ProjectID from the above list. And then how can I get a list of projects from Project table using the list of ProjectID.

First part of your question:
var projectIDs = db.ProjectMembers.Where(c=> c.UserID=u.UserID).select(pm=>pm.ProjectID) ;
2nd part:
if you are using Entity Framework, you should see a property called (project) for every entity of your ProjectMembers list, you can simply ignore my first part of this answer and go directly with this one
var projectsList = db.ProjectMembers.Where(c=> c.UserID=u.UserID).select(pm=>pm.Project) ;
the property may have a different name, give it a try and let me know what happened.
note: that if the retrieved projects were null, then your Entity framework is working wth Eager loading (Google it).
so in order to let the Entity framework generate the proper SQL syntax to retrieve the projects data, add an Include() to your query as the following:
var projectsList = db.ProjectMembers.Where(c=> c.UserID=u.UserID).Include("Projects").select(pm=>pm.Project) ;

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.

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.

Update db from Excel with Entity Framework 4.1

I'm new to EF 4.1 and try to move some code from to EF 4.1 (code first). Here is some background. I'm managing products for several companies, so I have a table "Product" with a column called "Company". I need to update (insert if not exist, otherwise update) this table from an Excel file containing products for a given company(let's say C1). Here is what I'm doing (using proprietary db access code and LINQ) :
Retrieve all products for company C1 as a list of products
For each product appearing in Excel:
Search the loaded list of products if the product from Excel exists already
If product does not exist then :
create new product instance
add product to database
add product to the list of loaded products
Else
update product in database
That's pretty straightforward but converting it to EF 4.1 does not seem that easy:
I can easily retrieve and filter all products from the context. I can also easily search for the Excel product in the loaded list. If not present, I can create the product and add it to the context. But how to mimic my "caching" system where I add the newly added product to my list of product loaded in memory (Excel file can contains several times the same product) ? Also when change the entity state and when to do savechanges ?
Christian
Here is a rough outline of how you can do this.
EF caches the loaded entities. You can use Local property to access it. This collection will be modified by EF when you add new entities.
context.Products.Where(p => p.Company == "C1").ToList();//force EF to load products
while(/*loop through excel file)
{
var product = context.Products.Local.Where(p=> p.Id == excelProductId);
if (product == null)
{
//insert
}
else
{
/update
}
}
context.SaveChanges();

How do I use a stored Procedure to return a single entity in Entity Framework 4?

New to Entity Framework .Using EF4. I have found articles and managed to use stored procedures to return a list of entities.
But cannot see/work out how you return a single entity.
Given that I have a stored procedure "GetCustomerById" that return a single customer How do I map it?
Using the Model Browser I right click on "Function Import" and I have added my StoredProcedure
however whatever I select does not seem to return a "Single Entity"
Am I missing the obvious?
thanks a lot for any link or suggestions
When you do Function Import you need to select the entity your SP returns from the drop down (i.e. Customer). The catch is EF does NOT directly returns Customer object as per your selection but System.Data.Objects.ObjectResult which implements IEnumerable.
To be more specific, here is the generated code for your function:
public ObjectResult<Customer> GetCustomerById(Nullable<global::System.Int32> Id)
That's because EF has no idea if your SP returns a single record or a list of them so it wraps the result inside ObjectResult. You can enumerate through this to get your Customer entity like any other IEnumerable object. For example:
Customer myCustomer = context.GetCustomerById(1).First();

Resources