2

I've been trying to find this, but I've not had luck. Say I have a database with 2 tables, person and address.

table person
id int
name varchar(50)
addressId int

table address
id int
street varchar(50)
country varchar(50)

In my data layer, I have a business object for Address, which is exposed to external callers. I found an expression that I could use to centralize my creation code at the SQL level. This way I don't have to write:

db.Address.Select( x => new Biz.Address{ street = x.street} ).ToList();  //and all the other properties etc

everywhere. Instead I can now do:

db.Address.Select(AddressDto.ToDto).ToList();

Using this code:

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
                   };
}

The problem is now that I am trying to do the same thing for the Person object, and I want to re-use this method to fill in the address. However I can't seem to utilize an expression in it.

class Person
{
    int Id;
    string Name;
    Address address;
}

internal static class PersonDto
{
    internal static readonly Expression<Func<Person, Biz.Person>> ToDto =
        src => new Biz.Person
                   {
                       Id = src.id,
                       Name = src.name,
                       address =  src.Address  //How do i set this to an expression?
                   };
}

The reason I ask for the expression, is because while it compiles fine if I use a normal method, it blows up at runtime, because it can't translate that to the object store. However, if I do:

address = AddressDto.ToDto(src.Address)  

the compiler rejects that, as it wants a method, delegate, or event. I'd love to find a way to do this. the idea I'm trying to implement is to basically centralize the code that maps the Entity to the business object, so that my other code is kept clean and maintenance is easier when the schema changes. If there is a different method signature I have to create and maintain, that'd be fine, as I'd place it in the same file and live with it. I just can't seem to find the magic combination that'll make this work.

Thanks!

Update from khan's suggestion.

That just moves this to a linq to objects area. I am trying to do this in the SQL end because of how some queries are built up, we don't want to call .ToList till later.

if I do:

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 }
               };
     }

Then that works. i just want to replace the new call.

4

1 回答 1

0

编译器不喜欢AddressDto.ToDto,因为当它只需要Func<>一个Expression<>Func<>

address = AddressDto.ToDto(src.Address)

从签名中删除Expression,看看它是否有效:

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)
                   };
}
于 2013-10-02T15:50:07.653 回答