如何使用LINQ将行分组为实体用逗号分隔值?

时间:2013-05-07 20:38:00

标签: c# sql linq comma

以下是我的LINQ查询,即我用来选择ITEMS

protected void Page_Load(object sender, EventArgs e)
{
    whatsmydiscountEntities ctx = new whatsmydiscountEntities();

    int IdRelationshipItems = Convert.ToInt32(Request.QueryString["IdRelationshipItems"]);
    int IdProductService = Convert.ToInt32(Request.QueryString["IdProductService"]);

    var Items = (from es in ctx.State
                join ie in ctx.ItemsStates on es.StateId equals ie.StateId 
                join i in ctx.Items on ie.IdItem equals i.IdItem 
                join iir in ctx.ItemsRelationshipItems on i.IdItem equals iir.IdItem
                join ir in ctx.RelationshipItems on iir.IdRelationshipItems equals ir.IdRelationshipItems 
                join ips in ctx.ItemsProductsServices on i.IdItem equals ips.IdItem 
                join ps in ctx.ProductsServices on ips.IdProductService equals ps.IdProductService
                 where iir.IdRelationshipItems == IdRelationshipItems
                && ips.IdProductService == IdProductService
                && ir.Active == 1 
                && i.Active == 1
                select new
                           {
                               ItemName = i.Name,
                               StateSigla = es.Sigla, 
                               ProductServiceName = ps.Ttitle, 
                               RelationshipItemName = ir.Name, 
                               RelationshipItemImage = ir.Image, 
                               RelationshipItemActive = ir.Active, 
                               ItemSite = i.Site,
                               ItemDescription = i.Description,
                               ItemAddress = i.Address,
                               Iteminformationdiscount = i.information_discount,
                               ItemLogo = i.Logo,
                               ItemActive = i.Active,
                               StateId = ie.StateId, 
                               IdRelationshipItems = iir.IdRelationshipItems,
                               IdProductService = ips.IdProductService
                            }).ToList();
}

如您所见,如果用户通过IdRelationshipItemsIdProductService,则每个州的结果将为1行。

对于每个具有相同信息的状态,我不想显示1行,而是只显示1行,所有状态用逗号分隔。我需要做些什么才能做到这一点?

1 个答案:

答案 0 :(得分:0)

我今天必须解决这个问题。我有一个看起来像这样的视图模型:

public class IndexViewModel
{
    public string Search { get; set; }
    public IPagedList<MembershipUser> Users { get; set; }
    public IEnumerable<string> Roles { get; set; }
    public bool IsRolesEnabled { get; set; }
    public IDictionary<string,string> Tags { get; set; }
}

我需要返回一个唯一的用户列表以及作为逗号分隔字符串分配给它们的所有标记。

数据存储如下:

“41FFEC0F-B920-4839-B0B5-​​862F8EDE25BD”,tag1
“41FFEC0F-B920-4839-B0B5-​​862F8EDE25BD”,tag2
“41FFEC0F-B920-4839-B0B5-​​862F8EDE25BD”,tag3

我需要看起来像这样的输出:

“41FFEC0F-B920-4839-B0B5-​​862F8EDE25BD”,“tag1,tag2,tag3”

我最终创建了一个UserId列表(我使用的是MembershipProvider,它将UserId公开为ProviderUserKey):

var userIdList = users.Select(usr => (Guid) usr.ProviderUserKey).ToList();

对象“users”是MembershipUser对象。然后我在我的服务中调用一个函数,像这样传递List:

Tags = _usersTagsService.FindAllTagsByUser(userIdList)

我的服务功能如下:

public IDictionary<string, string> FindAllTagsByUser(IList<Guid> users)
    {

        var query = (from ut in _db.UsersTags
                    join tagList in _db.Tags on ut.TagId equals tagList.Id
                    where users.Contains(ut.UserId)
                    select new {ut.UserId, tagList.Label}).ToList();

        var result = (from q in query
                     group q by q.UserId
                     into g
                     select new {g.Key, Tags = string.Join(", ", g.Select(tg => tg.Label))});

        return result.ToDictionary(x=>x.Key.ToString(),y=>y.Tags);
    }

我很确定这两个linq语句可能合并为一个,但我发现这种方式更容易阅读。仍只能访问数据库一次。

需要注意的事项

  1. 我最初只将IList用户传递给函数FindAllTagsByUser,而linq无法推断出类型,因此不会让我使用.Contains扩展方法。保持说linq to entities不支持Contains。
  2. 您需要在第一个查询上执行.ToList()以实现它,否则当您尝试使用string.Join创建逗号分隔列表时,您将遇到从linq到实体的麻烦。
  3. 祝你好运

    德纳什