【问题标题】:pass property to be used in lambda expression传递要在 lambda 表达式中使用的属性
【发布时间】:2019-02-11 03:06:50
【问题描述】:

我在使用泛型时遇到了问题。使用来自here 的示例,我想传递一个属性以在 EF Core 中使用。我有一种感觉,我把事情复杂化了。请注意,我想坚持使用 lamba 表达式,而不是传递诸如 nameof 之类的东西(我不能在 4.0 中使用)。

class Foo
{
        public string A { get; set; } // some unique string in DbSet for entity Person
        public string B { get; set; } // some unique string in DbSet for entity Company

        public int GetId<TEntity>(string match, Expression<Func<TEntity, string>> fieldToExamine,  Expression<Func<TEntity, int>> fieldWithId, System.Data.Entity.DbContext context)
            where TEntity : class
        {
            int retval = -1;
            if (!string.IsNullOrEmpty(match))
            {
                var expr = (MemberExpression)fieldToExamine.Body;
                var prop = (PropertyInfo)expr.Member;
                var expr2 = (MemberExpression)fieldWithId.Body;
                var idField = (PropertyInfo)expr2.Member;
                // this works because everything is explicit
                var entity = context.Set<Person>().SingleOrDefault(p => p.PersonName.Equals(match));
                // ... but I want that to be generic
                // how to reference the property to be evaluated?
                //var entity = context.Set<TEntity>().SingleOrDefault(p => ...); // <- HELP?!
                if (entity != null)
                {
                    retval = (int)entity.GetType().GetProperty(idField.Name).GetValue(entity, null);
                }
            }
            return retval;
        }
}

static void Main(string[] args)
{
// .. omitted database stuff ..
// (for Person) what I want is to match the Name field (here: p.Name) of the Person entity to the Foo property value (here: f.A) and return the database id stored in p.PersonId
int x = f.GetId<Person>(f.A, p => p.PersonName, p => p.PersonId, context);
// same for Company, but different values and fields
int y = f.GetId<Company>(f.B, p => p.CompanyName, p => p.CompanyId, context);
}

【问题讨论】:

    标签: c# entity-framework generics


    【解决方案1】:

    Person 类和Company 类将需要实现abstract classinterface

    public abstract class BaseEntity
    {
        public abstract int Id { get; set; }
        public abstract string Name { get; set; }
    }
    
    public class Person : BaseEntity
    {
        public int PersonId { get; set; }
        public override string Name { get; set; }
    
        public override int Id
        {
            get { return PersonId; }
            set { PersonId = value; }
        }
    }
    
    public class Company : BaseEntity
    {
        public int CompanyId { get; set; }
        public override string Name { get; set; }
    
        public override int Id
        {
            get { return CompanyId; }
            set { CompanyId = value; }
        }
    }
    

    那么你可以通过p.Namep.CompanyId

    var entity = context.Set<TEntity>().SingleOrDefault(p => p.Name.Equals(match));
    

    【讨论】:

    • 我已经准备好了这些课程。我想将它们的任何属性传递给SingleOrDefault()。我的问题是关于如何写SingleOrDefault(p=&gt;[?passed in property?].Equals(input))
    • 需要使用反射;我没有代码。您可能会从this 答案和 Jon Skeet 的原始答案中了解如何实现它。
    • 我想通了,但我想多了。我只需要从调用方法传递要在 SingleOrDefault() 中评估的表达式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多