I got the following 2 models:
public class CrawledImage
{
public CrawledImage()
{
CrawlDate = DateTime.UtcNow;
Status = ImageStatus.Unchecked;
}
public int ID { get; set; }
public DateTime CrawlDate { get; set; }
public string FileUrl { get; set; }
public long Bytes { get; set; }
public ImageStatus Status { get; set; }
public string FileName { get; set; }
public string Type { get; set; }
public virtual ICollection<ImageTag> ImageTags { get; set; }
}
public class ImageTag
{
public ImageTag()
{
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<CrawledImage> CrawledImages { get; set; }
}
Now what i want is to get a random CrawledImage, which is not the current image and which has all the tags i supply in a List (or HashSet of Collection that doesn't matter). Note that this is a many to many relation. I tried with the code below but i failed so i commented the part about the tags. I prefer to do this with Entity Framework.
public static CrawledImage GetRandomImage(int currentid, List<ImageTag> listtags)
{
try
{
while (true)
{
var randomId = new Random().Next(0, DbContext.CrawledImages.Count());
if (!randomId.Equals(currentid))
{
var image =
DbContext.CrawledImages.Single(i => i.ID.Equals(randomId));
//DbContext.CrawledImages.Where(i => i.ImageTags.Any(tag => listtags.Contains(tag))).First();
if (ProcessImage(image))
return image;
}
}
}
catch (Exception ex)
{
// Failed so return image with id -1
return new CrawledImage {ID = -1};
}
}
Thanks!
Edit: My question was marked as duplicated. It linked to a question only about retrieving a random record. I got this working. It is more about the many to many relation. Below there is an answer on that but that gives me the error:
An exception of type 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll but was not handled in user code Additional information: Unable to create a constant value of type 'ChickSpider.Logic.Models.ImageTag'. Only primitive types or enumeration types are supported in this context.
Edit 2:
With the help from Shoe's answer i figured it out. Here is the code
public static CrawledImage GetRandomImage(int currentid = 0, HashSet<string> tags = null)
{
if (tags == null)
return DbContext.CrawledImages.Where(c => c.ID != currentid).OrderBy(c => Guid.NewGuid()).First();
// ImageTags should match any given tags
return DbContext.CrawledImages.Where(c => c.ID != currentid && c.ImageTags.Any(ci => tags.Any(lt => lt == ci.Name))).OrderBy(c => Guid.NewGuid()).First();
// ImageTags should match all given tags
//return DbContext.CrawledImages.Where(c => c.ID != currentid && c.ImageTags.All(ci => tags.Any(lt => lt == ci.Name))).OrderBy(c => Guid.NewGuid()).First();
}