使用linq从列表列表中获取数据

时间:2015-10-28 16:26:37

标签: c# entity-framework linq

我有一个Title-Id的模型类:

public Word
{
   [key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public Guid WordId {get; set;};
   public string WordName {get; set;}
}

这句话存储在

public WordsStorage
{
        public WordsStorage()
        {
            CandWords = new HashSet<Word>();
        }

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

        public virtual ICollection<Word> CandWords { get; set; }
}

当我打电话时

var aaa = db.UserCWords.AsEnumerable().Select(e => e.CandWords ).Distinct(); 
var listOfLists = aaa.ToList();

我正在获取这些单词的列表 - 这是正确的。

var aaa = db.UserCWords.AsEnumerable().Select(e => e.CandWordsModelID ).Distinct(); 
    var listOfLists = aaa.ToList();

用于ID - 也可以正常工作

但如果我有自定义Word

Word myCustomWord = new Word();
myCustomWord.Id = Guid.NewGuid();
myCustomWord.WordName = "BadGuy";

如何获取所有CandWordsModelID,这个单词的值包含在哪里? 我试过了:

db.UserCWords.AsEnumerable().Where(e=>e.CandWords.Where(s=>s.WordName.Contains(myCustomWord.WordName))).Select(e => e.CandWordsModelID).Distinct()

但收到错误error CS0029: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<prj.Models.Word>' to 'bool'

3 个答案:

答案 0 :(得分:3)

试试这个:

var myWord = ...
db.UserCWords
    .Where(e => e.CandWords.Any(w => w.WordName.Contains(myWord.WordName)))
    .Select(e => e.Id)

不需要调用Distinct,因为没有两次处理单词存储。 您的代码问题似乎是您尝试使用返回Where的{​​{1}}的结果进行过滤。现在,如果您查看IEnumerable<T>方法的签名,您会看到它需要Where和谓词(IEnumerable<T>)并返回Func<T, bool>所以当您调用外部IEnumerable<T>时,它需要一个谓词,而且由于您在内部使用了另一个Where,因此您需要使用Where而不是Func<T, IEnumerable<T>>。您需要使用Func<T, bool>来实现您的目标

答案 1 :(得分:2)

更改此表达式:

e => e.CandWords.Where( s => s.WordName.Contains( myCustomWord.WordName ) )

使用Any代替Where

e => e.CandWords.Any( s => s.WordName.Contains( myCustomWord.WordName ) )

Where会针对匹配的实体过滤CandWords,其中Any将返回CandWords中符合您条件的任何实体的布尔值,我相信这是您的目标。

答案 2 :(得分:0)

抛出错误是因为你基本上有Where(... Where(...)...)外部Where需要一个布尔表达式,但内部Where()返回一个IEnumerable。

尝试更改内部Where()以使用Any()。如果Any()能够在集合中找到满足条件的对象,则它将返回true。

我很好奇为什么你需要在db.UserCWords上调用AsEnumerable()。如果UserCWords是IQueryable,你需要在调用AsEnumerable,ToList等之前调用Where和Select。否则你将从数据库中提取整个集合并评估客户端上的LINQ表达式(而不是将LINQ表达式转换为SQL 。)