LINQ自引用表过滤器关系

时间:2014-10-23 23:37:14

标签: c# sql-server linq ef-code-first linqkit

我有2个表CategoriesImages类别自我引用,ParentId为可空外键

Database Diagram Screenshot

代码优先级

public class Category {

    public int Id { get; set; }
    public string Name{ get; set; }
    public int? ParentId { get; set; }
    public bool IsDeleted { get; set; }
    public byte[] Timestamp { get; set; }

    public virtual Category Parent { get; set; }
    public virtual ICollection<Category> Parents { get; set; }

    public virtual ICollection<Image> Images { get; set; }
}


Public class Image {

    public int Id { get; set; }
    public int? CategoryId { get; set; }
    public string Source { get; set; }
    public string Description { get; set; }
    public bool IsDeleted { get; set; }
    public byte[] Timestamp { get; set; }

    // Foreign keys
    public virtual Category Category { get; set; }
}


public class CategoryMap : EntityTypeConfiguration<Category> {
    public CategoryMap() {
        // Primary Key
        HasKey(t => t.Id);

        // Properties
        Property(t => t.Name).IsRequired().HasMaxLength(250);
        Property(t => t.Timestamp).IsRequired().IsFixedLength().HasMaxLength(8).IsRowVersion();

        // Table & Column Mappings
        ToTable("Category");
        Property(t => t.Id).HasColumnName("Id");
        Property(t => t.ParentId).HasColumnName("ParentId");
        Property(t => t.Name).HasColumnName("Category");
        Property(t => t.IsDeleted).HasColumnName("IsDeleted");
        Property(t => t.Timestamp).HasColumnName("Timestamp");

        // Relationships
        HasOptional(t => t.Parent).WithMany(t => t.Parents)
                                  .HasForeignKey(d => d.ParentId)
                                  .WillCascadeOnDelete(false);
}

public class ProfileImageMap : EntityTypeConfiguration<ProfileImage> {

    public ProfileImageMap() {
        // Primary Key
        HasKey(t => t.Id);

        // Properties
        Property(t => t.Source).IsRequired().HasMaxLength(255);
        Property(t => t.Description).HasMaxLength(255);
        Property(t => t.Timestamp).IsRequired().IsFixedLength().HasMaxLength(8).IsRowVersion();

        // Table & Column Mappings
        ToTable("Images");
        Property(t => t.Id).HasColumnName("Id");
        Property(t => t.CategoryId ).HasColumnName("CategoryId ");
        Property(t => t.Source).HasColumnName("Source");
        Property(t => t.Description).HasColumnName("Description");
        Property(t => t.IsDeleted).HasColumnName("IsDeleted");
        Property(t => t.Timestamp).HasColumnName("Timestamp");

        // Relationships
        HasOptional(t => t.Category).WithMany(t => t.Images)
                                    .HasForeignKey(d => d.CategoryId);
    }
}

**背景**

    public DbSet<Category> Categories { get; set; }
    public DbSet<Image> Images { get; set; }

问题是我如何构建一个LINQ语句来返回一个基于Id的类别,父类别包含所有图像,不包括标记为IsDeleted = true的图像

是否可以在LINQLinqKit

中执行此操作

1 个答案:

答案 0 :(得分:2)

这将返回您应用过滤器所需的所有详细信息。唯一的复杂&#39; part是应用于Images属性的Where子句(我还添加了null检查,否则你可能得到NullReferenceException):

var categoryID = 2; //The ID you are searching for

var category = from c in categories
               where c.Id == categoryID 
               select new Category
               {
                   Id = c.Id,
                   Name = c.Name,
                   ParentId = c.ParentId,
                   IsDeleted = c.IsDeleted,
                   Timestamp = c.Timestamp,
                   Parent = c.Parent,
                   Images = c.Images == null ? 
                       (ICollection<Image>)new List<Image>() : 
                       (ICollection<Image>)c.Images.Where(i => i.IsDeleted = false).ToList()
               }.Single();

如果要返回所有父类别(即遍历层次结构),则一种方法是使用如下函数:

public IEnumerable<Category> GetParents(IEnumerable<Category> categories, Category child) 
{
    List<Category> parents = new List<Category>();
    var current = child.Parent;
    while (current != null)
    {
        parents.Add(parent);
        parent = parent.Parent;
    } 

    return parents;

}

现在你可以说:

category.Parents = GetParents(categories, category);
相关问题