如何在LINQ语句中使用Extension方法?

Bla*_*ise 2 c# linq foreach entity-framework

我有一个转换Address为oneline字符串的扩展方法:

public static class AddressExtensions
{
    public static string ToOneLine(this Address address)
    {
        var sb = new StringBuilder();
        sb.Append(address.Street);
        if (!string.IsNullOrWhiteSpace(address.City)) sb.Append(string.Format("{0}, ",address.City));
        if (!string.IsNullOrWhiteSpace(address.State)) sb.Append(string.Format("{0}, ", address.State));
        if (!string.IsNullOrWhiteSpace(address.Zip)) sb.Append(string.Format("{0}, ", address.Zip));
        return sb.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我用它将数据从域模型传输到我的DTO.下面的代码使用foreach和工作正常:

var entity=_repository.GetAll();
var model = new List<SummaryViewModel>();
        foreach (var e in entity)
        {
            model.Add(new SummaryViewModel
            {
                Address = e.Address.ToOneLine(),
                Name = e.Name,
                Id = e.Id
            });
        }
Run Code Online (Sandbox Code Playgroud)

但是在使用时LINQ,

        var model = entity.Select(e => new SummaryViewModel
        {
            Address = e.Address.ToOneLine(), Id = e.Id
        }).ToList();
Run Code Online (Sandbox Code Playgroud)

我有一个System.NotSupportedException.

LINQ to Entities does not recognize the method 'System.String ToOneLine
(Domain.Models.Address)' method, and this method cannot be translated 
into a store expression.
Run Code Online (Sandbox Code Playgroud)

发生了什么?我认为这两种方法都应该有用.

在LINQ语句中使用我的扩展方法的正确方法是什么?

D S*_*ley 6

Becasue EF无法将该扩展方法转换为SQL.最简单的解决方法是使用AsEnumerable()(实际上是这样foreach做)转换为Linq-to-Objects :

var model = entity.AsEnumerable()
                  .Select(e => new SummaryViewModel
{
    Address = e.Address.ToOneLine(), Id = e.Id
}).ToList();
Run Code Online (Sandbox Code Playgroud)

ToList使用AsEnumerable不在内存中创建其他集合不同,它只是绑定Linq调用Enumerable而不是Queryable,因此映射是在内存而不是在SQL中完成的.