在Linq to Entities Query中使用Expression选择返回字符串

时间:2015-08-11 16:33:07

标签: c# linq entity-framework

如何编写Linq to Entities查询以在SQL中模拟简单的concat表达式?即:

Select "<a href='https://tools.usps.com/go/TrackConfirmAction_input?qtc_tLabels1=" + [TrackingNbr] +">" + [TrackingNbr] + "</a>"

我知道我可以枚举结果,然后执行二次选择并使用这样的方法,但是如果可能的话,我想一次性完成。对于Linq to Entities来说,这似乎是一件相当简单的事情。

这是我的尝试,但失败了:

public IQueryable<ShippingContainerHeaderViewModel> ConvertEntityQueryToViewModelQuery(IQueryable<ShippingContainerHeader> entityQuery)
{
    var viewModelQuery = entityQuery.Select(entity => new ShippingContainerHeaderViewModel()
    {
        Id = entity.Id,
        //EntityDescription = entity.EntityDescription,
        OrderHeaderId = entity.OrderHeaderId,
        WebOrderId = entity.OrderHeader.WebOrderId,
        RequestedShipping = entity.OrderHeader.RequestedShippingMethod,
        Length = entity.Length,
        Width = entity.Width,
        Height = entity.Height,
        EstimatedWeight = entity.ShippingContainerDetails.Sum(dtls => dtls.Item.UnitWeight),
        Weight = entity.Weight,
        ShippingCarrier = entity.ShippingCarrier.Replace("_", " "),
        ShippingService = entity.ShippingService.Replace("_", " "),
        ShippingCost = entity.ShippingCost,
        ParcelShipmentId = entity.ParcelShipmentId,
        TrackingNumber = entity.TrackingNumber,
        TrackingNumberHyperLink = GetTrackingURL(entity.ShippingCarrier, entity.TrackingNumber),
        ShippingLabelURL = ShippingLabelURL,
        ShippingLabelZPL = entity.ShippingLabelZPL,
        ShipDateTimeUTC = entity.ShipDateTimeUTC,
        StatusId = entity.StatusId,
        Status = ((ShippingContainerHeader.StatusOptions)entity.StatusId).ToString(),
        CreatedById = entity.CreatedById,
        CreatedOn = entity.CreatedOn,
        ModifiedById = entity.ModifiedById,
        ModifiedOn = entity.ModifiedOn
    });

    return viewModelQuery;
}

我的方法:

private static string GetTrackingURL(string strCarrier, string strTrackingNumber)
{
    var shippingCarrierEnum = new CarrierType();
    shippingCarrierEnum = EnumHelper.GetEnumFromString<CarrierType>(strCarrier);

    //Get tracking URLs from all carriers http://verysimple.com/2011/07/06/ups-tracking-url/
    switch (shippingCarrierEnum)
    {
        case CarrierType.FedEx:
            return String.Format("<a href='http://www.fedex.com/Tracking?action=track&tracknumbers=http://www.fedex.com/Tracking?action=track&tracknumbers={0}'>{1}</a>", strTrackingNumber, strTrackingNumber);

        case CarrierType.UPS:
            return String.Format("<a href='http://wwwapps.ups.com/WebTracking/track?track=yes&trackNums={0}'>{1}</a>", strTrackingNumber, strTrackingNumber);

        case CarrierType.USPS:
            return String.Format("<a href='https://tools.usps.com/go/TrackConfirmAction_input?qtc_tLabels1={0}'>{1}</a>", strTrackingNumber, strTrackingNumber);

        default:
            return strTrackingNumber;
    }    
}

我的错误:

  

LINQ to Entities无法识别方法'GetTrackingURL(System.String,System.String)'方法,并且此方法无法转换为商店表达式。

尝试使用类似下面的内容创建一个Expression,但我不确定我是在咆哮正确的树还是如何正确实现它:

private static Expression<Func<ShippingContainerHeaderViewModel, string>> GetTrackingURLNew(string strCarrier, string strTrackingNumber)
{
    var shippingCarrierEnum = new CarrierType();
    shippingCarrierEnum = EnumHelper.GetEnumFromString<CarrierType>(strCarrier);

    //Get tracking URLs from all carriers http://verysimple.com/2011/07/06/ups-tracking-url/
    switch (shippingCarrierEnum)
    {
        case CarrierType.FedEx:
            return s => (String.Format("<a href='http://www.fedex.com/Tracking?action=track&tracknumbers=http://www.fedex.com/Tracking?action=track&tracknumbers={0}'>{1}</a>", s.TrackingNumber, s.TrackingNumber));

        case CarrierType.UPS:
            return s => (String.Format("<a href='http://wwwapps.ups.com/WebTracking/track?track=yes&trackNums={0}'>{1}</a>", s.TrackingNumber, s.TrackingNumber));

        case CarrierType.USPS:
            return s => (String.Format("<a href='https://tools.usps.com/go/TrackConfirmAction_input?qtc_tLabels1={0}'>{1}</a>", s.TrackingNumber, s.TrackingNumber));

        default:
            return s => s.TrackingNumber;
    }    
}

2 个答案:

答案 0 :(得分:1)

而不是这样做你可以创造一个属性:

public string TrackingNumberHyperLink {
get
 {
    return  GetTrackingURL(this.ShippingCarrier, this.TrackingNumber)
 }
}

如果你真的需要在查询中解析超链接,那么就这样做:

TrackingNumberHyperLink = entity.ShippingCarrier == "FedEx" ? "Url/Fedex" : (entity.ShippingCarrier == "UPS" ? "Url/UPS" : (entity.ShippingCarrier == "USPS" ? "Url/USPS" : entity.TrackingNumber))

答案 1 :(得分:1)

嗯,我没有看到任何关于代码的错误,但是entityQuery.Select继承了不在C#中的东西,我相信.ToList()应该可以做到这一点。

public IQueryable<ShippingContainerHeaderViewModel> ConvertEntityQueryToViewModelQuery(IQueryable<ShippingContainerHeader> entityQuery)
    {
        var viewModelQuery = entityQuery.ToList().Select(entity => new ShippingContainerHeaderViewModel()
        {