C#查询根据外键获取行

时间:2018-03-22 22:15:23

标签: c# sql asp.net database linq

我有两张桌子:

组件

Component

和组件配置文件

ComponentProfile

ComponentId是Component Profile

的外键

我想要做的是获取特定业务实体Id的所有组件,然后显示C#中那些组件ID的所有组件配置文件

我已经能够检索给定业务实体ID的所有组件

var component = context.Components.Where(i => i.BusinessEntityId == businessEntityId ).ToList();

我想退出不同的组件ID ,以便我可以从中获取所有组件配置文件。我如何实现这一点,组件ID对于每个配置文件都是唯一的。我希望,一旦我得到不同的组件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>());
                }


            }

这是一种简单的方法吗?

5 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,您可以使用Include

var components = context.Components
     .Include("ComponentsProfiles") // I believe it is plural, but you need to check.
     .Where(i => i.BusinessEntityId == businessEntityId )
     .ToList();

然后循环浏览组件,并获取相应的组件配置文件。

foreach(var component in components) {
   var componentProfiles = component.ComponentsProfiles;
}

仅供参考:最好在ComponentProfile表中包含唯一标识符列。

答案 1 :(得分:1)

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:

var componentGroups = components.GroupBy(c => c.ComponentId);

Now you can combine the components that have each ComponentId with the 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.

答案 2 :(得分:1)

此解决方案将所有代码组合到一个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

或者,如果您只需要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

答案 3 :(得分:0)

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;
        }

答案 4 :(得分:0)

ProfilesComponents之间存在一对多的关系:

  • 每个Component只有一个Profile(使用名称相当混乱的外键。我将使用ProfileId);
  • 每个Profile可以由零个或多个Components使用。

由于多个Profile可能会使用一个Components,因此可能会有几个“组件”。具有相同的外键值&#39; ProfileId`

  

我想为特定的企业实体ID获取所有组件   然后显示那些组件ID的所有组件配置文件

所以给定businessEntityId,您需要使用此Components找到所有businessEntityId。获得这些组件后,您可以找到属于这些组件的Profiles。如上所述,多个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