我有以下2个型号:
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; }
}
现在我想要的是获得一个随机的CrawledImage,它不是当前的图像,它包含我在List中提供的所有标记(或者Collection的HashSet并不重要)。请注意,这是多对多的关系。我尝试使用下面的代码,但我失败了所以我评论了有关标签的部分。我更喜欢使用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};
}
}
谢谢!
修改 我的问题被标记为重复。它只涉及一个关于检索随机记录的问题。我得到了这个工作。它更多的是关于多对多的关系。下面有一个答案,但这给了我错误:
类型&#39; System.NotSupportedException&#39;的例外情况发生在EntityFramework.SqlServer.dll但未在用户代码中处理附加信息:无法创建类型为&#39; ChickSpider.Logic.Models.ImageTag&#39;的常量值。在此上下文中仅支持原始类型或枚举类型。
编辑2:
在Shoe的答案的帮助下我明白了。这是代码
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();
}
答案 0 :(得分:0)
您可以用更少的代码完成此任务......
//All crawledImages not equal to current image and contain listtags
var crawledImages = DbContext.CrawledImages.Where(ci => ci.ID != currentid &&
ci.ImageTags.All(ci => listtags.Any(lt => lt.ID == ci.ID));
var random = new Random();
var randImage = crawledImages.OrderBy(ci => random.Next()).FirstOrDefault();
另一个注意事项(可能是个人偏好?)我不会从方法中返回虚拟数据。
catch (Exception ex)
{
//Log exception
//..
return null;
}