【问题标题】:Get random object in a many to many relation with Entity framework 6 [duplicate]在与实体框架6的多对多关系中获取随机对象[重复]
【发布时间】:2015-01-18 21:42:02
【问题描述】:

我有以下 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,它不是当前图像,它具有我在列表中提供的所有标签(或无关紧要的集合的 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};
    }
}

谢谢!

编辑: 我的问题被标记为重复。它只与一个关于检索随机记录的问题相关联。我得到了这个工作。它更多地是关于多对多的关系。下面有一个答案,但这给了我错误:

EntityFramework.SqlServer.dll 中出现“System.NotSupportedException”类型的异常,但未在用户代码中处理其他信息:无法创建“ChickSpider.Logic.Models.ImageTag”类型的常量值。此上下文仅支持原始类型或枚举类型。

编辑 2:

在鞋的回答的帮助下,我想通了。这是代码

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();
}

【问题讨论】:

    标签: asp.net-mvc entity-framework asp.net-mvc-5 entity-framework-6


    【解决方案1】:

    您也许可以用更少的代码完成此操作...

    //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;
    }
    

    【讨论】:

    • 我同意虚拟数据部分。但我在最后一行得到以下异常:EntityFramework.SqlServer.dll 中发生“System.NotSupportedException”类型的异常,但未在用户代码中处理附加信息:无法创建“ChickSpider.Logic”类型的常量值。模型.ImageTag'。此上下文仅支持原始类型或枚举类型。当我尝试在 crawledImages 中调试时,我看到了同样的异常。我还尝试删除两个集合上的虚拟,但这也无济于事。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2011-12-17
    相关资源
    最近更新 更多