Suppose I have a collection defined as:
IEnumerable<Employee> Employees;
Entity Employee has property Person.
I have loaded Employees from Ria service including Person with eager-loading.
Now I want to get the collection of Person from Employees, something like
IEnumerable<Person> People = Employees.Person;
How to use Linq to get all Person? any other solution for this case?
Unless I'm missing something, it should be as easy as (assuming Person isn't another collection):
var persons = Employees.Select(e => e.Person);
Try the following
IEnumerable<Employee> collection = ...;
IEnumerable<Person> persons = collection.Select(x => x.Person);
Related
I have two models: Person and RentedFilm
Person table fields:
id
name
RentedItem fields:
rid
film_id
rent_date
I need to add a new attribute to person model that contains last rent date but I don't know how. Already I have a getRentDates method that hasMany relations in defined inside it.
Would you help me?
Thank you.
Prepare relation like:
public function getLastRentItem()
{
return $this->hasMany(RentItem::class, ['rid' => 'id'])
->orderBy(['rent_date' => SORT_DESC])
->limit(1)
->one();
}
Use it like:
$model->lastRentItem ? $model->lastRentItem->rent_date : null;
*You have to adjust this code, because i didn't saw yours.
I have been struggling trying to get this one to work and my brain is shot...hoping someone can help out.
I have a table called Company which is the main entity returned from the query. The company table is linked to a table called Category through the table CompanyCategory. The category table has 2 fields that are relevant here: Name and Meaning. These fields contain the same data on a row...ie...Name = "Marketing" and Meaning = "MARKETING". This allows me to query by Meaning, while the display name could potentially change in the future. I will always query the category table by Meaning, and then display the Name.
Since a company can contain 1 to many categories, there are times when I want to return all companies that have a set of categories....say...all companies that are tied to marketing or public relations. Here is the query that I have right now that returns all companies with only the data I want.
IQueryable<ICompanyModel> q = base.Context.Set<KD.CompanyAdventures.Data.Implementation.Company>()
.Include(x => x.Address.City.FirstAdminDivision)
.Include(x => x.CompanyBioInfoes)
.Select(x => new CompanyModel
{
CompanyId = x.CompanyId,
Name = x.Name,
BusinessPhone = x.BusinessPhone,
PrimaryEmail = x.PrimaryEmail,
WebsiteUrl = x.WebsiteUrl,
LogoUrl = x.LogoUrl,
Address = new AddressModel
{
AddressId = x.AddressId,
Address1 = x.Address.Address1,
Address2 = x.Address.Address2,
PostalCode = x.Address.PostalCode,
City = new CityModel
{
CityId = x.Address.City.CityId,
Name = x.Address.City.Name,
FirstAdminDivision = new FirstAdminDivisionModel
{
FirstAdminDivisionId = x.Address.City.FirstAdminDivision.FirstAdminDivisionId,
Name = x.Address.City.FirstAdminDivision.Name
}
}
}
});
I am passing a List<string> to the method (GetCompanies) that has this LINQ query and I need to filter the companies that are returned by that list of category meanings that are being passed in. I have been able to get this to work in a test with 2 simple lists using the following (where list 1 = all employees (my wife and kids names) and list 2 is just the names of the my kids):
IQueryable<string> adultEmployees = employees.Where(emp => !kids.Contains(emp.ToString())).AsQueryable();
But I am not able to get this to work with the company and category example as I can't figure out how to drill down to the meaning with complex objects....ie...not list of strings.
Object classes used by the LINQ query look like the following:
CompanyModel [ CompanyId, CompanyName, List<CategoryModel> ]
CategoryModel [ CategoryId, Name, Meaning ]
Any help is greatly appreciated.
Assume that meanings is a list containing "marketing" and "public relations". If I understand this correctly, you can get companies having CategoryModels's Meaning equals "marketing" or "public relations" like so :
companies.Where(c => c.CategoryModels.Any(cm => meanings.Contains(cm.Meaning)))
I'm coming from TSQL + C# land and have been trying to adapt to linq and EF. Many-to-many relationships have been tripping me up. I have models with many-to-many relationships that I want to query from a database. Such as:
class Product{
public int ID {get;set;}
public string ProductName {get;set;}
public virtual ICollection<Tag> Tags {get;set;}
}
class Tag {
public int ID {get;set;}
public string TagName {get;set;}
public virtual ICollection<Product> Products {get;set;}
}
I'm able to get a product itself out of the DbContext, and then later fetch it's associated Tags like this:
// product exists in memory as a Product with an empty product.Tags
var query = from p in db.Product
from t in db.Tags
where p.ID == product.ID
select p.Tags;
Then I can assign the product.Tags with the fetched Tags. Obviously, this is very inefficient when dealing with multiple products if I have to query for every product.
With linq and EF, I want to be able to get a Product with all of its associated Tags in one round trip to the database. Also, I want to be able to get all Products and their associated Tags (or a filtered list of Products). How do would the linq look?
Edit:
Ok, after some more fiddling around, I've got this:
var query = db.Product.Include("Tags")
.Where(p => p.Tags.Any(t => t.Products.Select(m => m.ID).Contains(p.ID)));
This is almost what I need. The results are all products with tags. Missing are the products that don't have tags. I think of this as the equivalent of a SQL inner join. I want to left outer join the tags to the product, and return all products with tags optional. How to get all products with their associated tags without excluding products that have no tags?
Edit:
This was easier than I thought.
var query2 = db.Product.Include("Tags").DefaultIfEmpty();
This gets all the products and their respective tags, including products without tags. Hopefully it works for the right reasons...
The purpose of using an object-relational mapper like EF is that it maps relationships for you. If you are manually joining objects that have foreign keys in the database, you are doing it wrong.
See my question Why use LINQ Join on a simple one-many relationship?
The correct answer is simply context.Products.Include("Tags"), which will auto-magically join Products and Tags for you. This is literally the biggest (only?) benefit of using an ORM.
Relationship relation = new Relationship("campaignlist_association");
Entity campaign = (from c in orgServiceContext.CreateQuery("campaign")
select c).FirstOrDefault<Entity>();
foreach (Guid id in listsMarketingGuid)
{
Entity list = (from l in orgServiceContext.CreateQuery("list")
where l["listid"].Equals(id)
select l).FirstOrDefault<Entity>();
orgServiceContext.AddLink(campaign, relation, list);
orgServiceContext.AddLink(list, relation, campaign);
}
orgServiceContext.SaveChanges();
I would like to add a relation between a marketing list and a campaign but when the SaveChanges statment is executed I got an error "Associate is not supported for CampaignItem".
Do you any idea ?
Thanks
use Associate method as for building relationship:
_service.Associate(EntityLogicalName,EntityId,relationship,relatedEntities);
where EntityLogicalName is name of entity
EntityId is id of entity
relationship:wat kind of relationship
relatedentities:to which entiites u want to build relation of above entity.
it needs to call method AddItemCampaignRequest
I got the error
"Associate is not supported for CampaignItem"
when trying to associate product to campaign. This worked for me:
var request = new AddItemCampaignRequest
{
CampaignId = yourCampaign.Id,
EntityId = productToAssociate.Id,
EntityName = ProductEntity.EntityLogicalName,
};
_serviceProxy.Execute(request);
Creds to Mitch Milam
Hope this will help someone.
I have this contact list which I'm building using LINQ to SQL. The query to get a list of contacts is:
return db.Contacts.ToList();
In the list I also want to display each contact's primary e-mail address. To do this I first rewrite my query:
return (from db.Contacts
select c).ToList();
I found this nice way to do left joins:
return (from db.Contacts
from ce in ContactEmails.Where(x => x.ContactID == c.ContactID && c.IsPrimary).DefaultIfEmpty()
select c).ToList();
But now I want to add this PrimaryEmailAddress to my Contact object. To do this I have added a property (PrimaryEmailAddress) to the generated Contact class, using a partial class.
Is it possible in the LINQ query to add the value to c.PrimaryEmailAddress somehow? My solution right now is to create anonymous objects and then iterate them.
Here's one way to do it:
In your entity designer, create an association between your Contact class and your ContactEmail class (just guessing at your class names here). Here are some instructions on creating an association.
Then, configure your DataContext to load only your primary ContactEmail. Here are some instructions on filtering child data at the DataContext level.
And here is an entirely different way to do it:
In your partial Contact class, in your partial OnLoaded() method, query the primary ContactEmail. For example:
partial void OnLoaded()
{
// get your DataContext here
this.PrimaryContactEmail = db.ContactEmails
.Where(ce => ce.ContactID == this.ContactID && ce.IsPrimary)
.SingleOrDefault();
}