Reputation: 1608
I having a problem understanding some of the datatypes and datasets with MVC and LINQ. I am trying to populate a dropdownlist.
I receive the following error (noted below in the code)
"Unable to create a constant value of type 'vps_intranet.Models.Part'. Only primitive types or enumeration types are supported in this context."
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));
What do I need to change?
Upvotes: 0
Views: 77
Reputation: 218722
You are passing in a list of PartStructures
class objects to the Except
method. Except method uses the default equality comparer to compare the values.
If you are passing a custom class (not a simple value type like int
) , You should implement IEqualityComparer<T>
interface methods such as Equals
and GetHashCode
.
If you do not prefer to do that, You can get the Ids of your PartStructures collection and use that with the Contains
method.
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();
Upvotes: 1
Reputation: 4109
You are trying to use an Exclude
between two different data types. You have the Part
class and then the List<PartStructure>
. Do it by parts. First, get the parts. Then, cast it to the list of part structures and then do the exclude.
You have to implement IEqualityComparer<T>
Taken from: this post.
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();
}
}
This way you could do
var parts = db.Parts.Exclude(someList, new Compare());
Upvotes: 0