Tajuddin
Tajuddin

Reputation: 73

lambda expression in asp.net MVC

I am trying to select specific columns from a model but getting an error when I try to include select for the child entity. My model is -

public class Alert
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid AlertId { get; set; }

    [Display(Name = "Title"), MaxLength(160, ErrorMessage ="Title cannot be more than 200 characters long."), Required(ErrorMessage ="You must enter an alert title")]
   // [DataType(DataType.MultilineText)]
    public string Title { get; set; }


    [Display(Name = "Description"), MaxLength(8000, ErrorMessage = "Title cannot be more than 8000 characters long."), Required(ErrorMessage ="You must enter a description in {0} field")]
    [AllowHtml]
    [DataType(DataType.MultilineText)]
    public string Description { get; set; }

   [Display(Name = "Start Date"), Required(ErrorMessage ="You must enter the start date and time")]
   [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy hh:mm tt}", ApplyFormatInEditMode = false)]
  // [DataType(DataType.DateTime)]
    public DateTime StartDate { get; set; }

    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy hh:mm tt}", ApplyFormatInEditMode = false)]
    [Display(Name = "End Date")]
    public DateTime? EndDate { get; set; }

    [Display(Name = "Affected Site/s"), MaxLength(200,ErrorMessage ="You cannot enter more than 200 characters.")]
    public string SitesAffected { get; set; }


    [MaxLength(10)]
    public string Published { get; set; }

    [Display(Name = "Website Link"), MaxLength(200,ErrorMessage ="This cannot be more than 200 characters.")]
    public string WebLink { get; set; }


    [Display(Name ="Alert Type")]
    public int AId { get; set; }

    public virtual ICollection<Location> Location { get; set; }
    public virtual ICollection<AlertFile> Files { get; set; }
    [JsonIgnore]
    public virtual AlertType alertType {get; set;}

}

I can use the following lambda expression to produce json data through Web API.

var alerts = db.Alerts.Where(a=>a.alertType.Slug== alert && a.EndDate>=DateTime.Now && a.Published=="Yes").Select(s=>new
        {s.Title, s.Description, s.alertType.Slug, s.StartDate, s.EndDate, s.Location
        });


        return Request.CreateResponse(HttpStatusCode.OK, alerts.ToList());

The above code displays all the columns from the location table. I want to display specific columns from the location table and I tried the following code but getting error.

var alerts = db.Alerts.Where(a=>a.alertType.Slug== alert && a.EndDate>=DateTime.Now && a.Published=="Yes").Select(s=>new
        {s.Title, s.Description, s.alertType.Slug, s.StartDate, s.EndDate, s.Location.Select(l => new Location { l.Name, l.Latitude, l.Longitude, l.ParkId, l.Contact })
        });

Error: Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access.

Basically location is not allowing me to use select clause. Can anyone please help with this. Thanks in advance.

Upvotes: 1

Views: 5482

Answers (3)

teo van kot
teo van kot

Reputation: 12491

With this line:

s.Location.Select(l => new Location { l.Name, l.Latitude, l.Longitude, l.ParkId, l.Contact }

You don't assign your values to any property, you just select it if you want to assign your selected list to property like @Stephen Muecke said you should write:

Location = s.Location.Select(l => new Location { l.Name, l.Latitude, l.Longitude, l.ParkId, l.Contact }

Actually your full query should look like this:

var alerts = db.Alerts.Where(a=>a.alertType.Slug== alert && a.EndDate>=DateTime.Now && a.Published=="Yes").Select(s=>new
        { 
            Title = s.Title, 
            Description = s.Description, 
            AlertType = s.alertType.Slug, 
            StartDate = s.StartDate, 
            EndDate = s.EndDate, 
            Location = s.Location.Select(l => new Location { l.Name, l.Latitude, l.Longitude, l.ParkId, l.Contact })
        });

But C# compiler know how to name simple properties.

Upvotes: 3

Tajuddin
Tajuddin

Reputation: 73

In case if you someone has the same issue. I have changed the lambda expression to the following as Stephen suggested. It works fine now.

var alerts = db.Alerts.Where(a=>a.alertType.Slug== alert && a.EndDate>=DateTime.Now && a.Published=="Yes").Select(s=>new
        {s.Title, s.Description, s.alertType.Slug, s.StartDate, s.EndDate, locations= s.Location.Select(l => new { l.Name, l.Latitude, l.Longitude, l.ParkId, l.Contact })
        });

Upvotes: 0

Christoph Fink
Christoph Fink

Reputation: 23093

You need to name your property in the anonymous type:

var alerts = db.Alerts.Where(a=>a.alertType.Slug== alert && a.EndDate>=DateTime.Now && a.Published=="Yes").Select(s=>new
    {
      s.Title, s.Description, s.alertType.Slug, s.StartDate, s.EndDate,
      location = s.Location.Select(l => new Location { l.Name, l.Latitude, l.Longitude, l.ParkId, l.Contact })
    });

If you just select a simple property the name of the property is used automatically, but for other selects you need to name it on your own.

Upvotes: 2

Related Questions