2016-08-18 52 views
0

我对使用MVC和LINQ理解某些数据类型和数据集有困难。我正在尝试填充下拉列表。populate dropdownlist for mvc

我收到以下错误(在下面的代码说明)

“无法创建类型‘vps_intranet.Models.Part’的恒定值,只有原始类型或枚举类型在支持这个背景“。

PartsController.cs

private List<Part> partsNotPartOfStructure(int partID) 
{ 
    Part mainPart = db.Parts.Find(partID); 
    //var alreadySelected = db.Parts.Select(p => p.PartStructures_comp).Distinct(); 
    List<Part> parts = new List<Part>(); 

    List<PartStructures> excludeList = db.PartStructures1 
     .Where(p => p.mainPart_id == partID).ToList(); 

    parts = db.Parts.Where(c => c.PartStructures_comp 
     .Except((List<PartStructures>) excludeList)).ToList(); 
    //The line above gives the error... 
    //Unable to create a constant value of type 'vps_intranet.Models.Part'. 
    //Only primitive types or enumeration types are supported in this context.** 

    return parts; 
} 

public async Task<ActionResult> Details(int? id) 
{ 
    if (id == null) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    } 
    Part part = await db.Parts.FindAsync(id); 
    if (part == null) 
    { 
     return HttpNotFound(); 
    } 
    ViewData["AvailableParts"] = partsNotPartOfStructure(id.Value); 
    return View(part); 
} 

Details.cshtml

@model vps_intranet.Models.Part 

@{ 
    var fullList = (IEnumerable<vps_intranet.Models.Part>) ViewData["AvailableParts"]; 
    var availableParts = fullList.Select(p => new SelectListItem { Text = p.partNo.ToString(), Value = p.id }); 
} 

... 

@Html.DropDownListFor(model => model.PartStructures_comp, availableParts)); 

我需要做什么改变吗?

+1

确实[这](http://stackoverflow.com/questions/18929483/unable-to-create-a-constant-value-of-type -only-primitive-types-or-enumeration-ty)有帮助吗? –

+1

您正尝试在两种不同的数据类型之间使用“排除”。你有'Part'类,然后是'List '。按部件进行。首先,获取零件。然后,将其转换为零件结构列表,然后执行排除 –

+1

您可能想查看[ASP.Net MVC中的DropDownList](http://stackoverflow.com/questions/37818949/best-programming-practice-of -using-dropdownlist-in-asp-net-mvc/37819577#37819577) – Win

回答

1

您正在将类对象列表PartStructures传递给Except方法。除了方法使用默认的相等比较器来比较值。

如果你传递一个自定义类(不像int一个简单的值类型),你应该实现IEqualityComparer<T>接口中的方法,如EqualsGetHashCode

如果您不喜欢这样做,您可以获取PartStructures集合的ID并将其与Contains方法一起使用。

var excludeIdList = db.PartStructures1.Where(p => p.mainPart_id == partID) 
         .Select(g=>g.Id).ToList(); 

var parts = db.Parts 
      .Where(c => !c.PartStructures_comp.Any(g=>excludeIdList.Contains(g.Id))) 
      .ToList(); 
+0

感谢您的帮助。我更了解我做错了什么。但是,结果是排除列表中的部分,而不是列表的其余部分。我尝试使用除了但我得到一个错误。显然我有点学习。你将如何实施Except条款来代替包含? – Beengie

+0

正如我在答案中解释的那样,如果你想使用Except,你需要实现'Equals'和'GetHashCode'方法。我发布的解决方案有什么问题?它应该为您提供所有没有PartStructures_comp的部分,其中Ids与exlucdeIdList变量中的id相同。 – Shyju

+0

我在添加“”== false“之前实现了您的修复程序,并返回了包含的记录。”== false“后,它不返回任何记录 – Beengie

0

您试图在两种不同的数据类型之间使用Exclude。你有Part课,然后是List<PartStructure>。按部件进行。首先,获取零件。然后,将其转换为零件结构列表,然后执行排除。

您必须实现IEqualityComparer<T>

来自this岗位。

public class Compare : IEqualityComparer<Part> 
{ 
    public bool Equals(Part x, Part y) 
    { 
     return x.SomeProperty == y.SomeProperty; 
    } 
    public int GetHashCode(Part part) 
    { 
     return part.SomeProperty.GetHashCode(); 
    } 
} 

这种方式,你可以做

var parts = db.Parts.Exclude(someList, new Compare());