[英]C# query to fetch row based on foreign key
I have two tables:我有两个表:
Component组件
and Component Profile和组件配置文件
ComponentId
is a foreign key to Component Profile ComponentId
是组件配置文件的外键
What I want to do is fetch All Component for a specific Business entity Id and then display all component Profiles for those Component ids from C#我想要做的是获取特定业务实体 ID 的所有组件,然后从 C# 中显示这些组件 ID 的所有组件配置文件
I have been able to retrieve all components for a given business entity id我已经能够检索给定业务实体 ID 的所有组件
var component = context.Components.Where(i => i.BusinessEntityId == businessEntityId ).ToList();
I want to retrieve distinct component ids so that I can get all Component Profiles from it.我想检索不同的组件 ID,以便我可以从中获取所有组件配置文件。 How do i achieve this, Component Id is unique for each Profile.我如何实现这一点,每个配置文件的组件 ID 都是唯一的。 I am hoping that once I get distinct component Ids我希望一旦我获得了不同的组件 ID
foreach (var componentObject in componentObjects)
{
var componentId = componentObject.Id;
var componentProfile= context.ComponentProfiles.Where(i => i.ComponentId.Value == componentId);
if (componentProfile != null)
{
result.Add(componentProfile.Map<Libraries.Entities.ComponentProfile>());
}
}
What is an easy way to do this?有什么简单的方法可以做到这一点?
If I understand your question correctly, you can use Include .如果我正确理解您的问题,您可以使用Include 。
var components = context.Components
.Include("ComponentsProfiles") // I believe it is plural, but you need to check.
.Where(i => i.BusinessEntityId == businessEntityId )
.ToList();
You then loop through components, and get the corresponding component profiles.然后循环遍历组件,并获得相应的组件配置文件。
foreach(var component in components) {
var componentProfiles = component.ComponentsProfiles;
}
FYI: It is better to have unique identifier column in ComponentProfile table.仅供参考:最好在 ComponentProfile 表中有唯一标识符列。
I renamed your initial variable to be plural, since it returns multiple rows:我将您的初始变量重命名为复数,因为它返回多行:
var components = context.Components.Where(i => i.BusinessEntityId == businessEntityId).ToList();
Now you can group your components by ComponentId
so they are distinct:现在,您可以按ComponentId
对组件进行分组,使它们不同:
var componentGroups = components.GroupBy(c => c.ComponentId);
Now you can combine the components that have each ComponentId
with the ComponentProfile
:现在您可以将具有每个ComponentId
与ComponentProfile
组合起来:
var componentProfiles = componentGroups.Select(cg => new { Components = cg.Select(c => c), Profile = context.ComponentProfiles.Single(cp => cp.ComponentId == cg.Key) });
So componentProfiles
is an anonymous object that combines the list of Components
rows with what I enforced is the single ComponentProfiles
row that they use.所以componentProfiles
是一个匿名对象,它将Components
行列表与我强制执行的是它们使用的单个ComponentProfiles
行。
This solution combines all the code into a single Linq query.此解决方案将所有代码组合到一个 Linq 查询中。
var context = GetCoreDbEntityContext(businessEntityId);
var result = context.Components
.Where(i => i.BusinessEntityId == businessEntityId) // find relevant components
.Select(c => new { c.ComponentId, c.BusinessEntityId }) // isolate the fields needed
.Distinct() // find distinct combinations of fields
.Join( // inner join distinct combinations with ComponentProfiles
context.ComponentProfiles, // table or list to inner join with
c => c.ComponentId, // key selector from Components used in join
p => p.ComponentId, // key selector from ComponentProfiles used in join
(c, p) => new { // select individual fields or table(s) as needed
c.BusinessEntityId, // individual component business entity ID
c, // all Component fields
p // all ComponentProfile fields
})
.Select(r => r.p) // (optional) reduce columns to only ComponentProfiles
.ToList();
return result; // contains list of ComponentProfiles
Alternatively, if you only need the componentProfiles, you could do this.或者,如果您只需要 componentProfiles,您可以这样做。
var context = GetCoreDbEntityContext(businessEntityId);
var result = context.ComponentProfiles
.Where(p => context.Components
.Where(i => i.BusinessEntityId == businessEntityId) // find relevant components
.Any(c => c.ComponentId == p.ComponentId) // include rows with matching ComponentId
).ToList();
return result; // contains list of ComponentProfiles
This seemed to work out from all the pieces answered:这似乎从所有回答的部分中得到解决:
try
{
var context = GetCoreDbEntityContext(businessEntityId);
var components = context.Components.Where(i => i.BusinessEntityId == businessEntityId).ToList();
var componentIdsDistinct = components.Select(c => c.Id).Distinct();
foreach (var componentId in componentIdsDistinct)
{
var componentProfile = context.ComponentProfiles.SingleOrDefault(i => i.ComponentId == componentId);
if (componentProfile != null)
{
result.Add(componentProfile.Map<Libraries.Entities.ComponentProfile>());
}
}
return result;
}
There is a one-to-many relation between Profiles
and Components
: Profiles
和Components
之间存在一对多关系:
Component
has exactly one Profile
(using a foreign key with a rather confusing name. I'll use ProfileId
);每个Component
都只有一个Profile
(使用名称相当混乱的外键。我将使用ProfileId
);Profile
may be used by zero or more Components
.每个Profile
可以被零个或多个Components
。 Because one Profile
may be used by several Components
, there may be several 'Components' with the same foreign key value 'ProfileId`因为一个Profile
可能被多个Components
,所以可能有多个具有相同外键值 'ProfileId` 的 'Components'
I want to fetch All Component for a specific Business entity Id and then display all component Profiles for those Component ids我想获取特定业务实体 ID 的所有组件,然后显示这些组件 ID 的所有组件配置文件
So given a businessEntityId
, you need to find all Components
with this businessEntityId
.因此,给定一个businessEntityId
,您需要找到具有此businessEntityId
所有Components
。 Once you've got these components, you can find the Profiles
that belong to these components.获得这些组件后,您可以找到属于这些组件的Profiles
。 As said, several Components
may belong to the same Profile
, so you'll have to use Distinct
to remove duplicates.如前所述,多个Components
可能属于同一个Profile
,因此您必须使用Distinct
删除重复项。
var result = MyComponents
// keep only the components with businessEntityId
.Where(component => component.BusinessEntityId == businessEntitId)
.Join(MyProfiles, // Join with Profiles
component => component.ProfileId, // from every component take the foreign key
profile => profile.Id, // from every profile take the primary key
(component, profile) => // when they match
profile) // keep the matching profile
.Distinct() // and remove duplicates
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.