c# – LINQ to Entities和polymorphism

假设我有一个简单的模型:

public class Movie
{
    public int ID { get; set; }

    public string Name { get; set; }
}

和DbContext:

public class MoviesContext : DbContext
{
    ...
    public DbSet<Movie> Movies { get; set; }
}

另外,我在MoviesContext类中有一个方法可以通过子字符串过滤电影,如下所示:

return Movies.Where(m => m.Name.Contains(filterString)).Select(m => m);

现在假设我想添加一个新模型,比如说:

public class Person
{
    public int ID { get; set; }

    public string FirstName { get; set; }

    public string MiddleName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return FirstName + (MiddleName?.Length > 0 ? $" {MiddleName}" : "") + $" {LastName}"; } }
}

我还想按名称(即FullName)过滤人(DbSet人).我想要DRY,所以最好概括一下MoviesContext的过滤方法.而且,重要的是,我想在数据库级别进行过滤.所以我必须处理LINQ for Entities.

如果不是这样,任务很简单.我可以使用抽象类并添加一个执行“包含子串”逻辑的虚方法.或者,我可以使用界面.不幸的是,由于LINQ for Entities,我不能使用FullName属性(这不方便但可以忍受),我不能写这样的东西:

return dbset.Where(ent => ent.NameContains(filterString)).Select(ent => ent);

那么,如何解决这个问题呢?我找到了一些解决方案(几乎让我的头坏了),但我对此并不满意.我将单独发布我的解决方案,但我希望有一个更优雅的解决方案.

最佳答案 仔细阅读你的代码,而不是你的NameFilterable抽象类,你不能做这样的事情:

public interface IHasPredicateGetter<T> {
   [NotNull] Expression<Func<T, bool>> GetPredicateFromString([NotNull] string pValue);
}

public class Movie : IHasPredicateGetter<Movie> {
   public int ID { get; set; }
   public string Name { get; set; }

   public Expression<Func<Movie, bool>> GetPredicateFromString(string pValue) {
      return m => m.Name.Contains(pValue);
   }
}

例如,这可以防止您需要演员表.你很难理解你在这里想做什么,所以我不确定这是不是完整的事情.您仍然坚持使用可能是静态方法的实例方法,但是否则无法实现接口.

点赞