【问题标题】:Lambda Query on Generic Type T通用类型 T 的 Lambda 查询
【发布时间】:2020-01-26 11:32:05
【问题描述】:

我有基础模型类

public class BaseModel
{
  [Not Mapped]
  public string ExternalId;
}

基础模型类被两个子类继承

public class ChildA : BaseModel
{
  public string ExternalId;
}

public class ChildB : BaseModel
{
  public string Name;
}

所有子类都继承自 BaseModel。我已经在一些子类中声明了 ExternalId,所以我可以在我的抽象类中使用 linq。由于这些模型首先在 EF 模型中使用,这就是为什么在 BaseModel 中它具有 NotMapped 属性,因此 EF 不会生成此列。

这是抽象类

public abstract class Test<T> : ITest<T> where T : BaseModel, new()
{
    protected virtual IEnumerable<T> TestMethod(IEnumerable<T> listModels)
    {
        var items = listModels.Where<T>(i => i.ExternalId != "ABC").ToList();
    }
}

如何根据 ChildA 的 ExternalId 进行过滤

【问题讨论】:

  • 为什么有必要在ChildA 中声明ExternalId 吗?它隐藏了基本属性并且 - 好吧 - 会导致您的问题。
  • @RenéVogt 我只需要在 ChildA 中,并且我刚刚在 BaseModel 中声明,所以我可以在我的抽象方法中使用此属性用于 linq。

标签: linq generics lambda


【解决方案1】:

Demo on fiddle

你的设计有这样的问题

'ChildA.ExternalId' 隐藏继承的成员 'BaseModel.ExternalId'

您不应在 ChildA 类中声明 ExternalId

  1. TestMethod 没有返回值,所以你应该返回。

'Test.TestMethod(System.Collections.Generic.IEnumerable)':并非所有代码路径都返回值

你应该这样修复

public interface ITest<T> where T : BaseModel, new()
{
     IEnumerable<T> TestMethod(IEnumerable<T> listModels);
}


public class Test<T> : ITest<T> where T : BaseModel, new()
{
    public IEnumerable<T> TestMethod(IEnumerable<T> listModels)
    {
        return listModels.Where<T>(i => i.ExternalId != "ABC").ToList();
    }
}

【讨论】:

  • 我看过你的演示,但我更新了我的问题,所以你现在可能理解得更好了
  • 是的,您需要返回return listModels.Where&lt;T&gt;(i =&gt; i.ExternalId != "ABC").ToList();
  • 这能回答你的问题吗?如果您需要任何帮助,请告诉我@Arslan Pervaiz
  • 不,它没有完全帮助。也许我们可以在聊天室讨论
【解决方案2】:

这样写:

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            testFinal tf = new testFinal();

            List<BaseModel> mylist = new List<BaseModel>()
            {
                new ChildA(){ ExternalId = "1"},
                new ChildB(){ ExternalId = "1"},
                new ChildA(){ ExternalId = "2"},
                new ChildA(){ ExternalId = "3"},
                new ChildA(){ ExternalId = "1"},
                new ChildB(){ ExternalId = "2"},
            };

            var result = tf.TestMethod(mylist);
            Console.ReadLine();
        }
    }



    public class BaseModel
    {
        public string ExternalId;
    }


    public class ChildA : BaseModel
    {
        //public string ExternalId;
    }

    public class ChildB : BaseModel
    {
        public string Name;
    }


    public abstract class Test<T> : ITest<T> where T : BaseModel, new()
    {
        public IEnumerable<T> TestMethod(IEnumerable<T> listModels)
        {
            var items = listModels.Where<T>(i => i.ExternalId != "1").ToList();
            return items;
        }
    }


    public interface ITest<T> where T : BaseModel
    {
        IEnumerable<T> TestMethod(IEnumerable<T> listModels);
    }

    public class testFinal : Test<BaseModel>
    {

    }
}

【讨论】:

  • 你在抽象类中使用 BaseModel 类,你的 BaseModel 类有 ExternalId ,你在 Linq 中使用这个字段!因此,在您的子类中,您应该使用此字段,并且不要在子类中再次编写此字段。你的 senario 错了!
  • 你是什么意思我在孩子中使用了那个字段。您能否解释一下我如何访问派生类并更改属性
  • 在 ChildA 中,隐藏 BaseModel 的 ExtenalId !
猜你喜欢
  • 2016-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
相关资源
最近更新 更多