简体   繁体   中英

C# - How to convert Func<T, bool> to Func<dynamic, bool>?

Im using Entity Framework 4, I have an entity

public partial class UserEntity : EntityObject 
{
    public string id_user;
    public string pass;
    public DateTime date_added;
}

and a data transfer object with custom attributes

[DataTransferObject("UserEntity")]
public class User
{
    [EntityColumn("id_user")]
    public string idUser { get; set; }
    [EntityColumn("pass")]
    public string password { get; set; }
    [EntityColumn("date_added")]
    public string dateAdded { get; set; }
}

I convert the entity to dto and the dto to entity using these attributes with reflection, I'm using a generic repository for data access methods, when I want to make a query, using Enumerable.Where , to the ObjectSet of the entity, this require a Func<dynamic, bool> (dynamic because the program doesn't know the entity implementing the repository), this works but I want a Func<DTObject, bool> as parameter so I don't have to use entities in business layer, is there a way to achieve something like this?

public static Func<dynamic, bool> ConvertFunc<DTObject>(Func<DTObject, bool> predicate)
{
    /* do some magic to convert func */
    return newFunc;
}

Func<dynamic, bool> newFunc = ConvertFunc<User>(u => u.idUser == "admin" && u.password == "abc123");
/* newFunc = u => u.id_user == "admin" && u.pass == "abc123" */

I need to stop you right here. You are completely wrong on your approach. You need to use Queryable.Where<T>(this IQueryable<T> query, Expression<Func<T, bool>>) for EntityFramework to work. The method you would actually be using is Enumerable.Where<T>(this IEnumerable<T> set, Func<T, bool> predicate) , which would do the filtering IN MEMORY. This means the road you are going down will download your entire table into memory.

For this to work you need to be playing with the System.Linq.Expressions namespace. However, if this is going to work, without some insane amount of logic (more than already exists with Expressions). Your Dto signature will be exactly the same as your EntityObject .

Given this is true, what value does your DTO add (given the maintenance cost of the class)?

The only value I see is the decoupling of your domain logic from your data storage (ie you don't have EntityObject in your domain layer). However that problem was solved years ago with POCOs.

TLDR

XY problem. Use POCO instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM