Entity framework Linq至实体5重复使用表达式<;TEntity,TResult>;在另一个实体中

Entity framework Linq至实体5重复使用表达式<;TEntity,TResult>;在另一个实体中,entity-framework,Entity Framework,我一直想找到这个,但运气不好。假设我有一个数据库,有两个表,person和address table person id int name varchar(50) addressId int table address id int street varchar(50) country varchar(50) 在我的数据层中,我有一个针对Address的业务对象,它向外部调用者公开。我找到了一个表达式,可以用来在SQL级别集中创建代码。这样我就不用写了: db.Address.Select(

我一直想找到这个,但运气不好。假设我有一个数据库,有两个表,person和address

table person
id int
name varchar(50)
addressId int

table address
id int
street varchar(50)
country varchar(50)
在我的数据层中,我有一个针对Address的业务对象,它向外部调用者公开。我找到了一个表达式,可以用来在SQL级别集中创建代码。这样我就不用写了:

db.Address.Select( x => new Biz.Address{ street = x.street} ).ToList();  //and all the other properties etc
到处都是。相反,我现在可以做:

db.Address.Select(AddressDto.ToDto).ToList();
使用此代码:

internal static class AddressDto
{
    internal static readonly Expression<Func<Address, Biz.Address>> ToDto =
        src => new Biz.Address
                   {
                       Id = src.id,
                       Street = src.street,
                       Country = src.country
                   };
}
编译器拒绝它,因为它需要一个方法、委托或事件。我很想找到一个方法来做到这一点。我试图实现的想法是基本上集中将实体映射到业务对象的代码,这样我的其他代码就可以保持干净,并且在模式更改时维护就更容易了。如果有一个不同的方法签名我必须创建和维护,那就好了,因为我会将它放在同一个文件中并与之共存。我就是找不到能让这一切成功的神奇组合

谢谢

根据khan的建议进行更新。 这只是将其移动到linq到对象区域。我试图在SQL端这样做,因为有些查询是如何建立的,我们不想稍后调用.ToList

如果我这样做:

internal static class PersonDto
{
    internal static readonly Func<Person, Biz.Person> ToDto =
        src => new Biz.Person
               {
                   Id = src.id,
                   Name = src.name,
                   address =  new Biz.Address { id = src.Address.Id }
               };
     }
内部静态类PersonDto
{
内部静态只读函数ToDto=
src=>新业务人员
{
Id=src.Id,
Name=src.Name,
地址=新业务地址{id=src.address.id}
};
}

那就行了。我只想替换新的调用。

编译器不喜欢
AddressDto.ToDto
,因为您传递的是一个
Func
封装在
表达式中,而它只需要
Func

从签名中删除
表达式
,然后查看它是否有效:

internal static class AddressDto
{
    internal static readonly Func<Address, Biz.Address> ToDto =
        src => new Biz.Address
                   {
                       Id = src.id,
                       Street = src.street,
                       Country = src.country
                   };
}

internal static class PersonDto
{
    internal static readonly Func<Person, Biz.Person> ToDto =
        src => new Biz.Person
                   {
                       Id = src.id,
                       Name = src.name,
                       address =  AddressDto.ToDto(src.Address)
                   };
}
内部静态类地址到
{
内部静态只读函数ToDto=
src=>新业务地址
{
Id=src.Id,
街道=src.Street,
Country=src.Country
};
}
内部静态类PersonDto
{
内部静态只读函数ToDto=
src=>新业务人员
{
Id=src.Id,
Name=src.Name,
address=AddressDto.ToDto(src.address)
};
}

如果我只使用
Func
,而不使用其
表达式
包装器,则无法复制您的错误。如果您在执行选择之前调用ToList,则不会看到错误。当它试图将其转换为修复编译器的SQLWell时,会发生错误,但引发了一个异常:LINQ to Entities中不支持LINQ表达式节点类型“Invoke”。这就是为什么我认为一切本质上都是一个表达式。我看过一些关于编译表达式的内容,但我似乎找不到在这种情况下该如何编译。当出现错误时,请在
之前调用
ToList()
。选择(Func)
internal static class PersonDto
{
    internal static readonly Func<Person, Biz.Person> ToDto =
        src => new Biz.Person
               {
                   Id = src.id,
                   Name = src.name,
                   address =  new Biz.Address { id = src.Address.Id }
               };
     }
address = AddressDto.ToDto(src.Address)
internal static class AddressDto
{
    internal static readonly Func<Address, Biz.Address> ToDto =
        src => new Biz.Address
                   {
                       Id = src.id,
                       Street = src.street,
                       Country = src.country
                   };
}

internal static class PersonDto
{
    internal static readonly Func<Person, Biz.Person> ToDto =
        src => new Biz.Person
                   {
                       Id = src.id,
                       Name = src.name,
                       address =  AddressDto.ToDto(src.Address)
                   };
}