How to do this in lambda expression or linq?

2019-05-28 09:28发布

问题:

I have this requirement,

A product can have multiple images and only one default image. You can determine the default image of the product if the property isDefault is equal to true.

I want to do it in LINQ and lambda but I'm stucked in my code:

private class ProdcutImages
{
    public Int32 ID { get; set; }
    public String ProductID { get; set; }
    public Boolean IsDefault { get; set; }
    public Image Image { get; set; }
    public String FileName { get; set; }
}

public void SetDefaultImage(int productID)
{
    SqlConnection conn = getConnection();
    conn.Open();
    SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM product_images WHERE product_id = @ID", conn);
    da.SelectCommand.Parameters.Add(new SqlParameter("@ID", productID));


    DataTable dt = new DataTable();
    da.Fill(dt);

    var imageList = (from tr in dt.AsEnumerable()
                        select new ProdcutImages()
                        {
                            ID = tr.Field<int>("id"),
                            ProductID = tr.Field<string>("productId"),
                            IsDefault = tr.Field<bool>("isDefault"),
                            Image = tr.Field<Image>("image"),
                            FileName = tr.Field<string>("fileName")
                        }).ToList();

    pictureBox1.Image = // ???
    conn.Close();
}

回答1:

probably this:

var img = imageList.FirstOrDefault(i => i.IsDefault);
if (img != null) { pictureBox1.Image = img.Image; }

or, to take into account the case someone forgot to set the IsDefault field on any image:

var img = imageList.FirstOrDefault(i => i.IsDefault) ?? imageList.FirstOrDefault();
if (img != null) { pictureBox1.Image = img.Image; }

(this would use the first available image if none is set as default)



回答2:

If the method is SetDefaultImage, it would make sense to

SELECT * 
FROM product_images 
WHERE product_id = @ID and is_default = 1

or something similar. No point in bringing extra stuff from the database if you don't need to



回答3:

pictureBox1.Image = imageList.FirstOrDefault(pi => pi.IsDefault);

You do not even need to use the ToList for that.



回答4:

Do you just need to select the image out of a set for a particular product where isDefault=true?

I do things a little differently. I define a connection string globally (db) so I'm not certain if this works exactly as is for you, but you should be able to modify the first line to your methods.

Here's what I think you're asking for:

var imageList = db.DataTable
    .Where(w => w.ID == productID && w.IsDefault == true).FirstOrDefault();
pictureBox.Image = imageList.Image;

If there is any chance there are more than one images where IsDefault is true, I think you can look at using SingleOrDefault and trap the error.



标签: c# linq lambda