It is a bit difficult to distill from your question what you want to achieve. You give us some code, and tell us that the code doesn't do what you want, and ask us to give you the code that does give the requested result.
I hope I can extract your requirement from your code.
It seems that you have a table of Customers and a table of Groups. There seems to be a many-to-many relation between Customers and Groups: every Customer belongs to zero or more Groups, every Group has zero or more Customers that belong to this Group.
In relational databases, a many-to-many relation is implemented using a junction table. The junction table for the many-to-many between Customers and Groups is table CustomerXRefs
For every Customer in the table of Customers, you want its CustomerId, and a Property Institution.
The value of Institution is filled with a Name. This name is taken from the first Group of this Customer with GroupTypeId equal to 308.
There are two solutions for this:
- Use GroupJoins to get the Customers with their Groups and extract the Institution from these groups
- Use the capability of entity framework to translate the
virtual ICollection<...> into the corrrect GroupJoins. Use the virtual properties, entity framework translates them into the proper GroupJoin.
Usually the latter solution is easier, so we'll start with that one first.
The classes
If you have followed the entity framework conventions, you'll have classes similar to the following:
class Customer
{
public int Id {get; set;}
... // other properties
// every Customer belongs to zero or more Groups (many-to-many)
public virtual ICollection<Group> Groups {get; set;}
}
class Group
{
public int Id {get; set;}
public int GroupTypeId {get; set;}
public string Name {get; set;}
... // other properties
// every Group has to zero or more Customers(many-to-many)
public virtual ICollection<Customer> Customers {get; set;}
}
This is enough for entity framework to detect your many-to-many relation. Without even mentioning it, entity framework will create a junction table for you. Only if you want different names of tables or properties, you'll need fluent API or attributes.
In entity framework the columns of the table are represented by non-virtual properties; the virtual properties represent the relations between the tables: one-to-many, many-to-many, ...
Query using the virtual ICollection
var customersWithTheirGroups = dbContext.Customers.Select(customer => new
{
CustomerId = customer.Id,
Institution = customer.Groups.Where(group => group.GroupTypeId == 308)
.Select(group => new Institution
{
name = (ig.Name == "In1") ? "Institution 1" :
(ig.Name == "In2") ? "Institution 2 :
ig.Name,
})
.FirstOrDefault(),
});
BTW: note the parentheses around (ig.Name == "In1"). I think that if Name equals "In1" that you want a name "Institution 1", etc.
Is it correct that you have a class Institution with only one property?
class Institution
{
public string Name {get; set;}
}
Although it is allowed, it is a bit awkward, why not just select the InstitutionName?
.Select(group => (ig.Name == "In1") ? "Institution 1" :
(ig.Name == "In2") ? "Institution 2 :
ig.Name)
.FirstOrDefault(),
Anyway, entity framework knows the relations between the tables and will create the correct groupjoins with the junction tables.
This solution seems very natural.
Solution using GroupJoins
If you want to do the GroupJoin yourself, you'll need to define the junction table:
class CustomerXrefs
{
// every Xref in the junction table belongs to exactly one Customer:
public int CustomerId {get; set;}
// every Xref in the junction table belongs to exactly one Group:
public int GroupId {get; set;}
}
To get each Customer with its Groups, do a GroupJoin of the XRefs with the Customers, followed by another GroupJoin of Groups and XRefs.
var customersWithTheirGroups = dbContext.Customers.GroupJoin(dbContext.CustomerXRefs,
customer => customer.Id, // from every Customer take the Id
xref => xref.CustomerId, // from every xref take the foreign key to Customer
// Parameter resultSelector:
// for every Customer and all its xrefs make one new object:
(customer, xrefsOfThisCustomer) => new
{
Customer = customer,
// To get the Groups of this customer, GroupJoin the Groups with the xrefs:
Groups = dbContext.Groups
// GroupJoin the Group with the xrefs of this Customer
.GroupJoin(xrefsOfThisCustomer,
group => group.Id, // for every Group take the Id,
xRef => xref.GroupId, // for every xref of this customer take the foreign key
// parameter resultSelector:
// for every Group, and all xrefs of this Group that are xrefs of the Customer
// make one new:
(group, xrefs) => group).ToList(),
});
Result: all Customers, each with their Groups.
Select the institution:
var result = customersWithTheirGroups.Select(joinResult => new
{
CustomerId = joinResult.Customer.Id,
Institution = joinResult.Groups
// Keep only the Groups with the desired GroupTypeId
.Where(group => group.GroupTypeId == 308)
// The Select is similar as the Select in the virtual ICollection method:
.Select(group => new Institution
{
name = (ig.Name == "In1") ? "Institution 1" :
(ig.Name == "In2") ? "Institution 2 :
ig.Name,
})
.FirstOrDefault(),
});
Customer myCustomer = 0;orInstitution myInstitution = 0;and see what you get. What you are asking makes no sense, and makes me think there are lots of things to fix in your code.