简体   繁体   English

同时获取集合的第一个和最后一个元素

[英]Get First and Last element of a Collection at the same time

I'm currently working on a cross platform Project. 我目前正在从事跨平台项目。

I'm facing the problem when trying to map the model between WebDataLayer.Models and Shared.Models. 尝试在WebDataLayer.Models和Shared.Models之间映射模型时遇到了问题。

namespace WebDataLayer.Models
{
    public class Factory
    {
        public Guid Id { get; set; }
        public string Name { get; set; }

        public string Serie { get; set; }

        public Guid? AreaId { get; set; }

        public virtual ICollection<FactoryHotline> FactoryHotlines { get; set; }
}

public class FactoryHotline
    {
        public Guid Id { get; set; }
        public Guid FactoryId { get; set; }

        [Required]
        [MaxLength(256)]
        public string Caption { get; set; }

        [Required]
        [MaxLength(256)]
        public string Hotline { get; set; }
    }

This is model in Shared: 这是“共享”中的模型:

namespace Shared.Models
{
    [DataContract]
    public class Factory
    {
        [DataMember(Name = "id")]
        public Guid Id { get; set; }

        [DataMember(Name = "areaId")]
        public Guid AreaId { get; set; }

        [DataMember(Name = "name")]
        public string Name { get; set; }

        [DataMember(Name = "serie")]
        public string Serie { get; set; }

        [DataMember(Name = "hotLine1")]
        public FactoryHotline Hotline1 { get; set; }

        [DataMember(Name = "hotLine2")]
        public FactoryHotline Hotline2 { get; set; }
    }

public class FactoryHotline
    {
        [DataMember(IsRequired = true, Name = "Id")]
        public Guid Id { get; set; }

        [DataMember(Name = "FactoryId")]
        public Guid FactoryId { get; set; }

        [DataMember(Name = "Caption")]
        public string Caption { get; set; }

        [DataMember(Name = "Hotline")]
        public string Hotline { get; set; }
    }
}

This is code in Controller where I try to convert WebDatalayer.Models.Factory to Shared.Models.Factory : 这是Controller中的代码,我尝试将WebDatalayer.Models.Factory转换为Shared.Models.Factory

public ActionResult Edit()
        {
            var factories = _factoryService.All().OrderBy(p => p.Name);
            List<Shared.Models.Factory> response = new List<Shared.Models.Factory>();

            response =  factories.Select(k => new Shared.Models.Factory
             {
                 Id = k.Id,
                 Name = k.Name,
                 Serie = k.Serie,
                 Hotline1 = new Shared.Models.FactoryHotline {
                     Id = k.FactoryHotlines.FirstOrDefault().Id,
                     Caption = k.FactoryHotlines.FirstOrDefault().Caption,
                     Hotline = k.FactoryHotlines.FirstOrDefault().Hotline,
                     FactoryId = k.FactoryHotlines.FirstOrDefault().FactoryId
                 },
                 Hotline2 = new Shared.Models.FactoryHotline
                 {
                     Id = k.FactoryHotlines.LastOrDefault().Id,
                     Caption = k.FactoryHotlines.LastOrDefault().Caption,
                     Hotline = k.FactoryHotlines.LastOrDefault().Hotline,
                     FactoryId = k.FactoryHotlines.LastOrDefault().FactoryId
                 },
            }).OrderBy(f => f.Name).ToList();
            return View("Edit", response);
        }

But linq to entities does not recognize the method lastordefault , cannot use order descending because I also get First element at the same time. 但是linq to entities does not recognize the method lastordefault ,无法使用order descending因为我也同时获得了First元素。

Need help! 需要帮忙!

You look like you want to return all factories ordered by name, and for each factory, return the first and last hotline: 您似乎想返回按名称排序的所有工厂,并为每个工厂返回第一个和最后一个热线:

var query = factories.Select(f => new Shared.Models.Factory
    {
        Id = f.Id, 
        Name = f.Name,
        Serie = f.Serie,
        Hotline1 = f.FactoryHotLines
            .OrderBy(h => h.Id)
            .Select(h => new Shared.Models.FactoryHotline 
            {
                Id = h.Id,
                Caption = h.Caption,
                Hotline = h.Hotline,
                FactoryId = h.FactoryId
            }).FirstOrDefault(),
        Hotline2 = x.FactoryHotLines
            .OrderByDescending(h => h.Id)
            .Select(h => new Shared.Models.FactoryHotline 
            {
                Id = h.Id,
                Caption = h.Caption,
                Hotline = h.Hotline,
                FactoryId = h.FactoryId
            }).FirstOrDefault(),
     }).OrderBy(f => f.Name)
     .ToList();

Key thing here: When using FirstOrDefault() , always provide an OrderBy clause. 这里的关键点:使用FirstOrDefault() ,始终提供OrderBy子句。 Rather than relying on FirstOrDefault() to get each individual value, use it with the OrderBy() to get the entity then use Select() to reduce it down to the desired view model. 与其依赖FirstOrDefault()获取每个单独的值, FirstOrDefault()将其与OrderBy()一起使用以获取实体,然后使用Select()将其缩减为所需的视图模型。

The above example assumes you want the order they were added. 上面的示例假定您要添加它们的顺序。 (ID for identity-based records) This way we do the OrderBy() to get the first hotline, then an OrderByDescending() to get the second. (基于身份的记录的ID)通过这种方式,我们执行OrderBy()获得第一个热线,然后执行OrderByDescending()获得第二个热线。

I'm not sure if this is the cleanest solution, but you could chain .Where like this: 我不确定这是否是最干净的解决方案,但是您可以链接.Where如下所示:

.Where((v, i) => { return i == 0 || i == list.Count() -1; })

So.. 所以..

factories = factories.Where((v, i) => { return i == 0 || i == factories.Count() -1; })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM