2017-09-01 7 views
0

私はAutoMapperを初めて使用しています。私はPlayerFromDb.PositionにPlayerFromCache.PositionのようなタイプDbGeographyのプロパティをマップしたいと思っています。私はエラーを取得し続けるので、私は最も簡単なバージョンにコードを決裂:これは例外になりDbGeographyを使用したAutomapperの例外は「WellKnownValue ...」

Mapper.Initialize(cfg => 
{ 
    cfg.CreateMap<DbGeography, DbGeography>(); 
}); 

var pos1 = DbGeography.PointFromText($"POINT(11.0 12.0)", DbGeography.DefaultCoordinateSystemId); 
var pos2 = DbGeography.PointFromText($"POINT(22.0 23.0)", DbGeography.DefaultCoordinateSystemId); 

Mapper.Map(pos1, pos2); 

WellKnownValueプロパティはシリアル化および逆シリアル化をサポートすることを意図していないはずさ直接設定してください。

私は立ち往生しています。どんな助けもありがとう。

私はWellKnownValueを無視すると、その後、マッピングは動作しません:

Mapper.Initialize(cfg => 
{ 
    cfg.CreateMap<DbGeography, DbGeography>() 
     .ForMember(x => x.WellKnownValue, opt => opt.Ignore()); ; 
}); 

マッピングPOS2はまだ後22/23

答えて

2

DbGeographyが不変型である場合、そのコピーを作成する必要はありません。 DbGeographyの既存のインスタンスにマップする縮小コードは機能しませんが、それは動作するはずのものではなく、とにかく最終的な目標ではないため、そのことを忘れてしまいます。

cfg.CreateMap<DbGeography, DbGeography>();を削除すると、タイプDbGeographyのプロパティを複製せずに直接割り当てる必要があります。

+0

Lucianの答えを以下に私のコメントを参照してください。 – Tillito

+0

@Tillito私はAutoMapperが私が記述した方法で動作することを最低限のスタンドアロンプ​​ログラムで確認しました。あなたが投稿したコメント+回答があなたが求めた質問にどのように関係しているかは分かりません。あなたはあなたがここで質問したものとは異なる質問への回答を投稿することになったのではないでしょうか? – hvd

+0

はい、あなたは正しいです:問題は単純ではないことが判明しました。また、Entity Frameworkもエンボスしました。私はその質問を削除すべきだと思いますか?一方、私の答えは、dbgeographyフィールドを使ってオブジェクトをキャッシュしようとしている人を助け、私のようにEFとAutomapperを使うことができます... – Tillito

0

AMは、プロパティを設定することで動作し、DbGeographyは、その性質を持っていません設定することができます。他の理由でAMを使用したくない場合は、自分でマッピングする方が簡単です。

+0

私はこれを試しました。マッピングはそれ以上は機能しません。私はこれを私の質問に加えました。 – Tillito

+0

更新しました。設定するものはありません。 –

+0

問題は、現実世界での位置がほとんど変わらないため、ポジションはエンティティフレームワークの変更されたプロパティとして常にマークされ、パフォーマンスが大幅に低下することでした。私は、私のコード例をあまりにも単純化しました。 – Tillito

0

私は自分の問題をあまりにも単純化したことが判明しました。下記のように、プロパティのマッピング後に、プレーヤーをデータベースに保存したいのですが、変更があった場合のみです。残念ながら、Automapperで設定を行わなければ、Entity FrameworkはPositionが変更されたと常に仮定します。その結果、データベースに対する不安定な更新が多く発生します。

最後に、私は自分自身で問題を解決しました。これが他の人たちを助けることができれば嬉しいです

私の簡素化コード:だから

/// <summary> 
/// Players held in cached and stored in database using Entity Framework 
/// </summary> 
public class SimplePlayer 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public DbGeography Position { get; set; } 

    [NotMapped] 
    public string SerializedPosition 
    { 
     get { return Position.WellKnownValue.WellKnownText; } 
     set 
     { 
      //-- This is crucial for the redundant updates in EF: 
      if (value != Position.WellKnownValue.WellKnownText) 
      { 
       Position = DbGeography.FromText(value); 
      } 
     } 
    } 
} 

/// <summary> 
/// Get a player from the cache and only save 
/// it to the database if any property has changed 
/// </summary> 
/// <param name="context"></param> 
/// <returns></returns> 
public int UpdatePlayer(DbContext context) 
{ 
    Mapper.Initialize(cfg => 
    { 
     cfg.CreateMap<SimplePlayer, SimplePlayer>().ForMember(m => m.Position, opt => opt.Ignore()); 
    }); 

    //-- Get the player from the cache 
    var player = Game.Players.First(); 

    //-- When you un-comment this line, the result will be 1 
    //-- and the position will be changed in the database 
    // player.Position = GeographyHelper.CreatePoint(11, 11); 

    //-- Get the same player from the database 
    var playerFromDb = context.Set<Player>().Find(player.ID); 

    //-- Map the properties 
    Mapper.Map(player, playerFromDb); 

    //-- Save changes to the database if there are any 
    int countChanges = context.SaveChanges(); 

    return countChanges; 
} 

、私にとってどのプロパティが変更された場合UpdatePlayerのみ1をもたらすことは非常に重要でした。

ご質問いただきまして申し訳ありませんが、ご利用いただきありがとうございます。

関連する問題