How to select only particular columns from navigation properties using EF - c#

I'm trying to select only 2 columns from the navigation properties but unable to do it, can anyone let me know how can I achieve this?
It works good default way(selecting all columns) :
var productreceipts = db.productreceipts.Include(p => p.employee).Include(p => p.productmaster).Include(p => p.vendor);
What I want:
Select only 2 columns form each of employee, productmaster, vendor tables.
I know how to select if I have only one table:
var productreceipt = db.productreceipts.Select(p => new { p.ReceiptId, p.ReceivedBy });
EDIT :
I want to select all properties of first table(productreceipts) and only a few selected from others.
Any help will be much appreciated.
Thanks in advance.

You can use like :
var productreceipts = db.productreceipts.Include(p => p.employee).
.Select(p => new { propertyName = p.productmaster.SomeProperty })

If you have lazy loading enabled then you can directly use
.Select(p => new { ProductId = p.productmaster.ProductId }
else you will have to take inner join and select individual columns in single select.

Try this:
var productreceipt = db.productreceipts
.Select(p =>
new { productreceipts_prop_1 = p.productreceipts_prop_1,
productreceipts_prop_2 = p.productreceipts_prop_2,
productreceipts_prop_3 = p.productreceipts_prop_3,
productreceipts_prop_4 = p.productreceipts_prop_4,
employee_prop_1 = p.employee.employee_prop_1,
employee_prop_2 = p.employee.employee_prop_2,
productmaster_prop_1 = p.productmaster.productmaster_prop_1,
productmaster_prop_2 = p.productmaster.productmaster_prop_2,
vendor_prop_1 = p.vendor.vendor_prop_1,
vendor_prop_1 = p.vendor.vendor_prop_1,
});
EDIT:
There is no need to use the .Include() You can directly use the navigator property to retrieve the data.

Related

LINQ troubles in C# using Entity Framework

I have a few tables and this is what I need to achieve.
This gets all the rows from one table
var FRA = from prod in _cctDBContext.Fra
where prod.ActTypeId == 1
From within that, I get all the rows where ActTypeID.
Then I need to query another table from with the ID's get from that
foreach (var item in FRA)
{
var FRSA = _cctDBContext.Frsa
.Select(p => new { p.Fraid, p.Frsa1,
p.Frsaid, p.CoreId,
p.RelToEstId, p.ScopingSrc,
p.Mandatory })
.Where(p => p.Fraid == item.Fraid)
.ToList();
}
I then need to push each one of these to Entity Framework. I usually do it this way:
foreach (var item in FRA)
{
var FinanicalReportingActivity = new FinancialReportingActivity { FinancialReportingActivityId = item.Fraid, ScopingSourceType = item.ScopingSrc, Name = item.Fra1, MandatoryIndicator = item.Mandatory, WorkEffortTypeId = 0 };
_clDBContext.FinancialReportingActivity.AddRange(FinanicalReportingActivity);
}
But because I have used 2 for each loops, I cannot get the variables to work because I cannot find a way to get local variables as the entity context.
Can anyone think of a better way to code this?
Thanks
It looks like you can do this as a single join:
var query =
from prod in _cctDBContext.Fra
where prod.ActTypeId == 1
join p in _cctDBContext.Frsa on prod.Fraid equals p.Fraid
select new
{
p.Fraid,
p.Frsa1,
p.Frsaid,
p.CoreId,
p.RelToEstId,
p.ScopingSrc,
p.Mandatory
};
It looks like you are loading data from one set of entities from one database and want to create matching similar entities in another database.
Navigation properties would help considerably here. Frsa appear to be a child collection under a Fra, so this could be (if not already) wired up as a collection within the Fra entity:
Then you only need to conduct a single query and have access to each Fra and it's associated Frsa details. In your case you look to be more interested in the associated FRSA details to populate this ReportingActivity:
var details = _cctDBContext.Fra
.Where(x => x.ActTypeId == 1)
.SelectMany(x => x.Frsa.Select(p => new
{
p.Fraid,
p.Frsa1,
p.Frsaid,
p.CoreId,
p.RelToEstId,
p.ScopingSrc,
p.Mandatory
}).ToList();
though if the relationship is bi-directional where a Fra contains Frsas, and a Frsa contains a reference back to the Fra, then this could be simplified to:
var details = _cctDBContext.Frsa
.Where(x => x.Fra.ActTypeId == 1)
.Select(p => new
{
p.Fraid,
p.Frsa1,
p.Frsaid,
p.CoreId,
p.RelToEstId,
p.ScopingSrc,
p.Mandatory
}).ToList();
Either of those should give you the details from the FRSA to populate your reporting entity.

How to display LINQ Lambda Expression to a textbox

I am kind of new to Lambda Expressions, I have tried to work out a simple solution to the following task I have set myself.
A customer has a collection of cars. Use LINQ to get a total number of cars he has.
Code below, not sure if this is correct? My second question is how do you display the TotalNumberCars to a textbox?
using (Entities dbcontext = new Entities())
{
var ListByOwner = from c in dbcontext.Owners
where c.OwnerID == OwnerID
group c by c.Cars into g
select new
{
Owner = g.Key,
TotalNumberCars = g.Sum(x => x.Cars)
};
lblTotalCars.Text = ListByOwner.ToList();
}
I don't know how your entity data model is structured, but I would do it like this:
using (var dbContext = new Entities())
{
var numberOfCars = dbContext.Cars.Count(c => c.OwnerId == OwnderId);
lblTotalCars.Text = numberOfCars.ToString();
}
If there's no c.OwnerId then maybe you can access it by typing c.Owner.OwnerId.
ListByOwner.ToList() is an array (generic list) of your new items from your Select projection. Each item is a dynamic entity with two properties of Owner and TotalNumberCars. You need to index or foreach into the list, extract what is needed into a string and that can be your text.
Such as lblTotalCars.Text = ListByOwner[0].Owner; will display the first item's owner.
Take this and fill in what you need.
check this code
lblTotalCars.Text = ListByOwner.ToList().sum(c=>c.TotalNumberCars).ToString();

How to filter results in Entity Framework with multiple select box

I have three tables for blog posts:
post_table for posts properties like post_id, post_title and etc.
category_table including of two columns such as category_id and category_name
and post_category_table that is an interface table for relationship between post_table and category_table and it has two foreign key columns such as post_id and category_id.
Note that each post can have one or more categories.
multiple select box (image)
Now I have an multiple select box (like attachment image) for categories that user be able to select one or more categories. When user select one or more categories from select box, results should be limited to selected categories.
How do I write "Where" condition for this problem with Entity Framework?
My code is:
var query = context.post_Table
.Select(postinfo => new {
post_title = postinfo.post_title,
post_date = postinfo.post_date,
post_id=postinfo.post_id,
post_category = postinfo.post_category_table.Select(cc => new {
cc0=cc.category_id,
cc1 = cc.category_table.category_name,
}),
}).Where(???)
You should be able to get a collection of category ids from the multiple selection box (the ids of the selected categories).
Let's call that selectedCategoryIds and let's assume it's an IEnumerable<int>.
To filter the results according to the selected categories you'd do this:
var query = context.post_Table
.Select(postinfo => new
{
post_title = postinfo.post_title,
post_date = postinfo.post_date,
post_id=postinfo.post_id,
post_category = postinfo.post_category_table.Select(cc => new
{
cc0 = cc.category_id,
cc1 = cc.category_table.category_name,
})
})
.Where(info => info.post_category.Any(c => selectedCategoryIds.Contains(c.cc0)));
Edit
If you have some conditional logic you can split and compose the query accordingly:
var query = context.post_Table
.Select(postinfo => new
{
post_title = postinfo.post_title,
post_date = postinfo.post_date,
post_id=postinfo.post_id,
post_category = postinfo.post_category_table.Select(cc => new
{
cc0 = cc.category_id,
cc1 = cc.category_table.category_name,
})
});
if(selectedCategoryIds != null && selectedCategoryIds.Any())
{
query = query.Where(info => info.post_category.Any(c => selectedCategoryIds.Contains(c.cc0)));
}
However if your conditional logic is more complex than the trivial example above please take a look at my answer to a previous question on why you should use a predicate builder.

Linq: let Count result into a specified column

I've got a table Installation which can contains one or many Equipements.
And for functionnal reasons, I've overwritten my table Installation and added a field NbrEquipements.
I want to fill this field with Linq, but I'm stuck...
Due to special reasons, there is no relation between these to tables. So, no Installation.Equipements member into my class. Therefore, no Installation.Equipements.Count...
I'm trying some stuff. Here is my code:
var query = RepoInstallation.AsQueryable();
// Some filter
query = query.Where(i => i.City.RegionId == pRegionId));
int?[] etatIds = { 2, 3 };
query = (from i in query
select new Installation
{
NbrEquipements= (from e in RepoEquipement.AsQueryable()
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e.SasId
).Count()
});
But with this try, I got this error:
The entity or complex type 'myModel.Installation' cannot be constructed in a LINQ to Entities query
I've tried some other stuff but I'm always turning around...
Another thing that can be useful for me: It would be great to fill a field called Equipements which is a List<Equipement>.
After that, I would be able to Count this list...
Is it possible ?
Tell me if I'm not clear.
Thanks in advance.
Here is the final code:
//In the class:
[Dependency]
public MyEntities MyEntities { get; set; }
//My Methode code:
var query = MyEntities .SasInstallations.AsQueryable();
// Some filter
query = query.Where(i => i.City.RegionId == pRegionId));
var liste = new List<Installation>();
var queryWithListEquipements =
from i in query
select new
{
Ins = i,
EquipementsTemp = (from eq in MyEntities.Equipements.AsQueryable()
where eq.SpecialId == i.SpecialId
&& (etatIds.Contains(eq.SasEquEtat))
select eq
).ToList()
};
var listWithListEquipements = queryWithListEquipements.ToList();
foreach (var anonymousItem in listWithListEquipements)
{
var ins = anonymousItem.Ins;
ins.Equipements = anonymousItem.EquipementsTemp;
ins.NumberEquipements = ins.Equipements.Count();
liste.Add(ins);
}
return liste;
By the way, this is very very fast (even the listing of Equipements). So this is working exactly has I wished. Thanks again for your help everyone!
Use an anonymous type. EF does not like to instantiate entity classes inside a query.
var results = (from i in query
select new
{
NbrEquipements= (from e in RepoEquipement
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e.SasId
).Count()
})
.ToList();
Notice how I used select new instead of select new Installation.
You can then use the data inside the list (which is now in memory) to create instances of type Installation if you want like this:
var installations = results.Select(x =>
new Installation
{
NbrEquipements = x.NbrEquipements
}).ToList();
Here is how to obtain the list of equipment for each installation entity:
var results = (from i in query
select new
{
Installation = i,
Equipment = (from e in RepoEquipement
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e).ToList()
})
.ToList();
This will return a list of anonymous objects. Each object will contain a property called Installation and another property called Equipment (which is a list). You can easily convert this list (of anonymous objects) to another list of whatever type that you want.

Entity Framework select distinct name

How can I do this SQL query with Entity Framework?
SELECT DISTINCT NAME FROM TestAddresses
Using lambda expression..
var result = EFContext.TestAddresses.Select(m => m.Name).Distinct();
Another variation using where,
var result = EFContext.TestAddresses
.Where(a => a.age > 10)//if you have any condition
.Select(m => m.name).Distinct();
Another variation using sql like syntax
var result = (from recordset
in EFContext.TestAddresses
.where(a => a.city = 'NY')//if you have any condition
.select new
{
recordset.name
}).Distinct();
Try this:
var results = (from ta in context.TestAddresses
select ta.Name).Distinct();
This will give you an IEnumerable<string> - you can call .ToList() on it to get a List<string>.
The way that #alliswell showed is completely valid, and there's another way! :)
var result = EFContext.TestAddresses
.GroupBy(ta => ta.Name)
.Select(ta => ta.Key);
I hope it'll be useful to someone.
DBContext.TestAddresses.Select(m => m.NAME).Distinct();
if you have multiple column do like this:
DBContext.TestAddresses.Select(m => new {m.NAME, m.ID}).Distinct();
In this example no duplicate CategoryId and no CategoryName i hope this will help you
Entity-Framework Select Distinct Name:
Suppose if you are using Views in which you are using multiple tables and you want to apply distinct in that case first you have to store value in variable & then you can apply Distinct on that variable like this one....
public List<Item_Img_Sal_VIEW> GetItemDescription(int ItemNo)
{
var Result= db.Item_Img_Sal_VIEW.Where(p => p.ItemID == ItemNo).ToList();
return Result.Distinct().ToList();
}
Or you can try this Simple Example
Public Function GetUniqueLocation() As List(Of Integer)
Return db.LoginUsers.Select(Function(p) p.LocID).Distinct().ToList()
End Function
use Select().Distinct()
for example
DBContext db = new DBContext();
var data= db.User_Food_UserIntakeFood .Select( ).Distinct();
In order to avoid ORDER BY items must appear in the select list if SELECT DISTINCT error, the best should be
var results = (
from ta in DBContext.TestAddresses
select ta.Name
)
.Distinct()
.OrderBy( x => 1);
Entity-Framework Select Distinct Name:
Suppose if you are want every first data of particular column of each group ;
var data = objDb.TableName.GroupBy(dt => dt.ColumnName).Select(dt => new { dt.Key }).ToList();
foreach (var item in data)
{
var data2= objDb.TableName.Where(dt=>dt.ColumnName==item.Key).Select(dt=>new {dt.SelectYourColumn}).Distinct().FirstOrDefault();
//Eg.
{
ListBox1.Items.Add(data2.ColumnName);
}
}

Categories

Resources