如何以 Func 类型的表达式作为参数调用方法

How to call method with Expression of type Func as parameter

我使用了在线教程中看到的 Repository 模式...

除 find 方法外,一切正常,我不知道如何使用它,而且我很难理解 Expressions 或 Func 类型。我以前用过linq和lambda,但我是初学者,仍然不能流利地使用它...

public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
    return Context.Set<TEntity>().Where(predicate);
}

我有这个型号class:

public partial class Artikl
{
        [Browsable(false)]
        public int IDArtikli { get; set; }
        public string Barkod { get; set; }
        [DisplayName("Šifra")]
        public Nullable<int> Sifra { get; set; }
        public string Naziv { get; set; }
        [DisplayName("JM")]
        public string JedinicaMjere { get; set; }
        public decimal Tarifa { get; set; }
        [DisplayName("Prodajna")]
        public Nullable<decimal> ProdajnaCijena { get; set; }
        [Browsable(false)]
        public Nullable<bool> Flag { get; set; }
        public Nullable<decimal> Kalo { get; set; }
        [DisplayName("Nabavna")]
        public Nullable<decimal> NabavnaCijena { get; set; }
        [DisplayName("Veleprodajna")]
        public Nullable<decimal> VeleprodajnaCijena { get; set; }
        public Nullable<decimal> Zalihe { get; set; }
 }

我的问题是如何获得基于 属性 "Sifra" 的 Artikl 项目。我不知道如何调用这个方法...

private void txtSifra_TextChanged(object sender, EventArgs e)
{
     var artikl = _UnitOfWork.Artikl.Find(???);
     txtNaziv.Text = artikl.Naziv;
}

你需要传一个lambda expression来满足Expression<Func<TEntity, bool>> predicate。您可以通过这样做获得基于 属性 "Sifra" 的项目:

var artikl = _UnitOfWork.Artikl.Find(q => q.Sifra == "some int value").FirstOrDefault();

希望对您有所帮助!

Expression<Func<TEntity, bool>>的用法是这样的,传入一个lambda表达式(伪代码)即可:

var result = context.set.Find(x => x.Property == value);

所以在你的情况下:

var artiklList = _UnitOfWork.Artikl.Find(x => x.Sifra == 1);
var artikl = artiklList.FirstOrDefault();

不要忘记 return .FirstOrDefault() 因为 Find 结果将是 IEnumerable<T>.

其他答案已经解释了如何使用表达式,但我想提一件事,在使用所谓的存储库模式时经常被忽视:

public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
    return Context.Set<TEntity>().Where(predicate);
}

这个 returns IEnumerable<TEntity> 并且因为这个:

var result = _UnitOfWork.Artikl.Find(c => c.Sifra == 1).FirstOrDefault()

不会在数据库中执行整个查询。数据库查询(大致)如下所示:

select * from Artikl where Sifra = 1 -- < not efficient

而不是这样:

select top 1 * from Artikl where Sifra = 1 -- < efficient

要解决此问题,您必须 return IQueryable:

public IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
    return Context.Set<TEntity>().Where(predicate);
}

或者为您要进行的每个查询创建单独的方法:

public TEntity FindFirst(Expression<Func<TEntity, bool>> predicate)
{
    return Context.Set<TEntity>().Where(predicate).FirstOrDefault();
}