Linq To Entities通用类和接口

时间:2014-11-11 17:41:57

标签: c# generics linq-to-entities

public class CoreEntity
{
    public int Id { get; set; }
    //some additional common fields like insertedBy, insertedAt etc
}
public interface IUniqueObject
{
    Guid Uid { get; set; }
}
public class Tag : CoreEntity
{
    public string TagName { get; set; }
}

public class ItemTags : CoreEntity
{
    public Guid TaggedItemUid { get; set; }
    public int TagId { get; set; }
}


public class Repository<T>
    where T : CoreEntity
{
    public DbSet<T> TheEntitySet { get; set; }
    public DbSet<ItemTags> ItemTagSet { get; set; }
    public IQueryable<T> AddTagsFilter(IQueryable<T> query, List<int> tags)
    {
        var ts = ItemTagSet;
        if (typeof (T) is IUniqueObject)
        {
            query = query.Where(f => ts.Any(e => e.TaggedItemUid == ((IUniqueObject)f).Uid && tags.Contains(e.TagId));
        }
        return query;
    }
}

//usage
public class Departman : CoreEntity, IUniqueObject
{
    public Guid Uid { get; set; }
    //some other fields
}
class Test
{

    void xx()
    {
        var r = new Repository<Departman>();
    }
}

为了解决问题的目的,这些课程已经简化了,而不仅仅是在这里展示的。问题是Linq to Entities不允许转换((IUniqueObject)f)。用户。那么如何应用标签过滤器知道泛型类型T实现了IUniqueObject接口。我尝试使用一些GenericMethod和“T2 where:CoreEntity,IUniqueObject”但我无法将类型T转换为T2,无论如何 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

LinqToEntities中的Where语句将转换为SQL语法。每条指令都必须可以转换为SQL - 这意味着没有转换。还在考虑一个更有帮助的答案。我认为您需要为不同的查询类型设置不同的功能,例如:添加如下方法:

public IQueryable<T> AddTagsFilterToUniqueObject(IQueryable<T> query, 
                                   List<int> tags) where T : IUniqueObject 
{ 
    var ts = ItemTagSet;

    query = query.Where(f => ts.Any(e => e.TaggedItemUid == (f.Uid && tags.Contains(e.TagId));

    return query;
}