简体   繁体   English

Linq没有命令,也没有区别

[英]Linq not ordered and not distinct

I have an MVC 5 .net app, using Razor view engine. 我有一个使用Razor视图引擎的MVC 5 .net应用程序。 I am trying to populate a dropdown list from entity framework model. 我正在尝试从实体框架模型填充一个下拉列表。 Here is my linq statement in the controller: 这是我在控制器中的linq语句:

private void populateDistrictTypeDropDown(object selectedDistrict = null){
    var query = from d in db.roadways
                orderby d.district
                select d;
    ViewBag.District = new SelectList(query, "district", "District", selectedDistrict).Distinct();
}

but it doesn't seem to be ordered or only grabbing the distinct items, which it looks like to me it should be. 但它似乎不是有序的,或只是抓住不同的物品,在我看来应该如此。

Here is what it looks like: 看起来像这样:

在此处输入图片说明

Here is my view: 这是我的看法:

@Html.DropDownListFor(xy => xy.SelectedDistrictTypeIds, new SelectList(Model.DistrictTypesList, "Id", "district")) 

And here is the model: 这是模型:

public class SearchPageModel
{
    public IEnumerable<lkp_roadwaytypes> FacilityTypes { get; set; } // use this to get roadway type, which = FacilityTypes
    public IEnumerable<survey> Surveys { get; set; } // use this to get period to search for from surveydate
    public IEnumerable<roadway> Roadways { get; set; }// use this to get Disctricts and Cost Centers

    // below is for drop down select list on search page
    public int[] SelectedDistrictTypeIds { get; set; }
    public List<roadway> DistrictTypesList { get; set; }

    public int[] SelectedPeriodIds { get; set; }
    public List<survey> PeriodList { get; set; }

    public MainContext myContext = new MainContext();

    public List<roadway>GetDistrictTypes(){
        return myContext.roadways.Where(a=>a.district != null).ToList();
    }
}

EDIT for Sami's answer: 编辑萨米的答案:

created a new class with an Equals method as - 用Equals方法创建了一个新类-

class District
{
    public int ID {get; set;}
    public int Name { get; set; }

    public bool Equals(District d1, District d2)
    {
        if(d1.ID == d2.ID){return true;}
        else{return false;}
    }
}

changed the query as - 将查询更改为-

private void populateDistrictTypeDropDown(object selectedDistrict = null){
    var query = (from d in db.roadways
                orderby d.district
                select new District {ID = d.ID, Name = d.district}).Distinct();
    ViewBag.District = new SelectList(query, "ID", "Name", selectedDistrict);

}

but I'm getting the same result, so I must be missing something you said. 但我得到的结果是一样的,所以我一定想念你说的话。 Am I supposed to call the equals method somehow, or is the .Distinct() doing that for me? 我应该以某种方式调用equals方法,还是.Distinct()为我这样做?

Edit 2: 编辑2:

I noticed I wasn't using the ViewBag in the view, so I changed it to this: 我注意到我没有在视图中使用ViewBag,因此将其更改为:

@Html.DropDownListFor(vx => vx.SelectedDistrictTypeIds, new SelectList(ViewBag.District))

but now my box looks like this: 但是现在我的盒子看起来像这样:

在此处输入图片说明

Don't distinct the SelectList, instead distinct the query: 不要区分SelectList,而是区分查询:

var query = (from d in db.roadways
            orderby d.district
            select d.district)
            .Distinct;

Also, as per Sami you need to order and distinct on District, not Roadway (see the changed select line) 另外,根据萨米族人的需要,您需要在地区(而不是道路)上订购和区分(请参阅更改的选择行)

You're currently using LINQ to select objects of type roadway . 您目前正在使用LINQ选择roadway类型的对象。 If you try to distinct those, you will always get all objects back, since they are distinct, unless you have defined a equality comparison function. 如果尝试区分这些对象,则除非它们定义了相等比较函数,否则始终会取回所有对象,因为它们是不同的。

I guess you don't want to compare roadway s to each other always by district ID, so I would suggest you create a new class for storing district name and ID, return that type of object from your query, define comparison operations for it and then you can distinct it. 我猜您不希望总是通过地区ID相互比较roadway ,因此建议您创建一个用于存储地区名称和ID的新类,从查询中返回该类型的对象,为其定义比较操作,然后那么您就可以区分它。

So your query would be something like 所以您的查询将类似于

var query = (from d in db.roadways
                    orderby d.district
                    select new District { ID = d.Id, Name = d.district }).Distinct();

Then if you have defined an Equals method, your list should be distincted by whatever you define there (probably a comparison of Id?) 然后,如果您定义了一个Equals方法,则列表应该与在此定义的内容区分开(可能是ID的比较?)

You will also have to bind the SelectList to use the new properties in the District class and not the roadway class. 您还必须绑定SelectList以使用District类而不是道路类中的新属性。

Ok, not sure if this is the best way to do it, but it works for me: 好的,不确定这是否是最好的方法,但是对我有用:

put this in my Model: 把它放在我的模型中:

// populate district drop down
    public IEnumerable<int> populateDistrictTypeDropDown(){
        var query = (from d in myContext.roadways
                    orderby d.district                        
                    select d.district).ToList().Distinct();            

        return query;
    }

this is my controller: 这是我的控制器:

 public ActionResult Search()
        {   

            SearchPageModel spm = new SearchPageModel();       

            spm.DistrictTypesList = spm.populateDistrictTypeDropDown();

            return View(spm);
        }

and this is my view: 这是我的看法:

 @Html.DropDownListFor(xy => xy.SelectedDistrictTypeIds, new SelectList(Model.DistrictTypesList))

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

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