3
votes

I'm currently working on a search page. I need to only return a list of themedetails for themes that contain all of the themetag id's that are stored in the int[] ST. Currently the line (ST == null ? true : ST.Contains(b.ThemeTagID)) seems to give me an error

Additional information: Unable to create a null constant value of type 'System.Int32[]'. Only entity types, enumeration types or primitive types are supported in this context.

    public ActionResult Index(int ProviderID = 0, string Description = null, int[] ST = null)
    {

        var themedetail = from t in db.ThemeDetail
                          from b in t.ThemeTags
                          where (
                          (string.IsNullOrEmpty(Description) ? true : t.Description.ToLower().Contains(Description.ToLower())) &&
                          (ProviderID == 0 ? true : t.ProviderID == ProviderID) &&
                          (ST == null ? true : ST.Contains(b.ThemeTagID))
                              )
                          select t;

        ViewBag.ProviderID = new SelectList(db.ProviderDetails, "ProviderID", "ProviderName");
        ViewBag.MultiselectFeatures = new MultiSelectList(db.ThemeFeatures, "ThemeFeatureID", "ThemeFeaturesName");
        ViewBag.MultiselectTags = new MultiSelectList(db.ThemeTags, "ThemeTagID", "TagName");

        return View(themedetail.ToList());
    }

The Models are...

[Table("ThemeDetail")]
public class ThemeDetail : Entity
{
    [Required]
    [Display(Name = "Name")]
    public string ThemeName { get; set; }
    public ThemeDetail()
    {
        ThemeFeatures = new List<ThemeFeature>();
        ThemeTags = new List<ThemeTag>();
        ThemeImages = new List<ThemeImage>();
    }

    public virtual ICollection<ThemeFeature> ThemeFeatures { get; set; }
    public virtual ICollection<ThemeTag> ThemeTags { get; set; }
    public virtual ICollection<ThemeImage> ThemeImages { get; set; }
}

[Table("ThemeTags")]
public class ThemeTag
{
    [Key]
    [Display(Name = "Theme Tag ID")]
    public int ThemeTagID { get; set; }

    [Display(Name = "Tag Name")]
    [Required]
    public string TagName { get; set; }

    public virtual ICollection<ThemeDetail> ThemeDetail { get; set; }
}
1

1 Answers

5
votes

You're using ST inside your query but it can't be translated to SQL because ST is int[] and can be null) and in SQL there isn't any notion of array.

If you change your query to avoid null checking EF will be able to translate that query using WHERE ThemeTagID IN (...) with values provided from your list (be careful if list may come from another query with thousands of elements):

public ActionResult Index(int ProviderID = 0...
{
    if (ST == null)
        ST = new int[0];

Then simply change this:

(ST == null ? true : ST.Contains(b.ThemeTagID))

To this:

ST.Contains(b.ThemeTagID)