使用类似表达式

时间:2016-03-23 11:32:58

标签: c# entity-framework linq

在实体框架中加入多对多的最佳方法是什么。

我有一个标签类

喜爱 我有一个Tag类

[Table("tblTags")]
public class Tag
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    [Column("fld_int_id")]
    public virtual int Id { get; set; }

    [Column("fld_str_name")]
    public virtual string Name { get; set; }

    public virtual ICollection<DocumentUploadEntity> Documents { get; set; }
}

我有一个文件类

  [Table("tblUploadDocument")]
    public class DocumentUploadEntity 
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Column("fld_int_ID")]
        public int ID { get; set; }


        public virtual ICollection<Tag> Tags { get; set; }
    }

我像这样映射它们:

modelBuilder.Entity<DocumentUploadEntity>()
    .HasMany(x => x.Tags)
    .WithMany(x => x.Documents)
    .Map(x =>
    {
        x.ToTable("tblUploadDocumentsTags");
        x.MapLeftKey("fld_int_document_id");
        x.MapRightKey("fld_int_tag_id");
    });

我想在类似的表达式中搜索包含标记名称的任何文档。如果我在sql中这样做我会这样做:

SELECT * FROM tblUploadDocument d
INNER JOIN tblUploadDocumentsTags ud
ON fld_int_document_id = d.fld_int_id
INNER JOIN tbltags t
ON ud.fld_int_tag_id = t.fld_int_id
WHERE t.fld_str_name like 'foo%';

请原谅表名和字段名,这不是我的意思。

如何使用linq和实体框架执行此操作。

2 个答案:

答案 0 :(得分:2)

var documents = DbContext.Tags.Where(x => x.Name.StartsWith("foo"))
                .SelectMany(y => y.Documents).ToList()

答案 1 :(得分:1)

EF的美妙之处在于你可以从任何一方开始并使用导航属性到达many-to-many关系的另一面。在幕后,EF将使用link表和必要的连接。

例如,您可以从DocumentUploadEntity开始:

var documents = 
    from document in db.DocumentUploadEntities
    where document.Tags.Any(tag => tag.Name.Contains("foo"))
    select document;

或者您可以从Tag开始:

var documents = 
    from tags in db.Tags
    where tag.Name.Contains("foo")
    from document in tag.Documents
    select document;

更新::正如@James Dev在评论中正确陈述的那样,SQL LIKE 'foo%的等价物是Name.StartsWith("foo")