4

AutoMapper 3 を使用して、Integer プロパティを持つクラスを String プロパティを持つ別のクラスに投影しようとしています。

クエリが実行されると、次の例外が発生します。

System.NotSupportedException: LINQ to Entities はメソッド 'System.String ToString()' メソッドを認識せず、このメソッドはストア式に変換できません。

コードの関連部分は次のとおりです。

public partial class Lookup
{
    public int LookupId { get; set; }
    public int LookupTypeId { get; set; }
    public string Value { get; set; }
    public int SequencialOrder { get; set; }

    public virtual LookupType LookupType { get; set; }
}

public class LookupProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Lookup, SelectListItem>()
            .ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.LookupId.ToString()))
            .ForMember(dest => dest.Text, opt => opt.MapFrom(src => src.Value));

    }
}

クエリは次のようになります。

Provinces = _db.Lookups.Project().To<SelectListItem>().ToList()

質問:

適切なマッピングを行い、Linq To Entities 内で引き続き動作するように LookupProfile を構成する方法はありますか? または、Linq to Entities でプロジェクションを機能させる別の方法はありますか?

4

2 に答える 2

4

解決策は、 SqlFunctions.StringConvert関数を使用することでした。

すべてが機能するように変更されたプロファイル コードを次に示します。

public class LookupProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Lookup, SelectListItem>()
            .ForMember(dest => dest.Value, opt => opt.MapFrom(src => SqlFunctions.StringConvert((double)src.LookupId)))
            .ForMember(dest => dest.Text, opt => opt.MapFrom(src => src.Value));

    }
}
于 2013-10-05T14:59:51.313 に答える
2

他の誰かが私と同じ問題に遭遇した場合に備えて、この回答をここに残しておきます。

現在受け入れられている回答の問題の 1 つは、ヘルパーを介してクライアント側の検証を使用する ASP.NET MVC プロジェクトを使用している場合、ID フィールドの検証エラーが発生することです (数値の場合) The field [field] must be a number.。 result fromSqlFunctions.StringConvertは先頭にいくつかのスペースを含む文字列を返すため、目立たないバリデーターはそれを数値として認識しません。

私が自分でこの問題を解決した方法は、から継承し、元のプロパティを隠し、独自のセッターを実装するジェネリックSelectListItem<T>クラスを作成することでした。SelectListItemValueValue

public class SelectListItem<T> : SelectListItem
{
    public new T Value {
        set {
            base.Value = value.ToString();
        }
        // Kind of a hack that I had to add 
        // otherwise the code won't compile
        get {
            return default(T);
        }
    }
}

次に、Automapper プロファイルで、次のようにアイテムをマッピングします。

public class LookupProfile : Profile
{
    protected override void Configure()
    {
        //Use whatever datatype is appropriate: decimal, int, short, etc
        CreateMap<Lookup, SelectListItem<int>>()
            .ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.LookupId))
            .ForMember(dest => dest.Text, opt => opt.MapFrom(src => src.Value));

    }
}

そして最後に、サービス レイヤーで、エンティティをジェネリック クラスにマップし、IEnumerable<SelectListItem>.

public IEnumerable<SelectListItem> GetList() {
    return _db.Lookups.Project().To<SelectListItem<int>>().ToList();
}

このようにして、Value末尾のスペースなしでプロパティの適切な値を取得できます。

于 2014-01-01T22:16:28.610 に答える