2013-03-19 13 views
5

n層アプリケーションでは、linq-to-sqlには、子エンティティセットを持つ切断されたエンティティを更新するための明確な解決策がないようです。linqからsqlへの子エンティティを持つ切断されたエンティティの更新

私はそうLocationエンティティがLocationZipCodesEntitySetを持っているでしょう

public partial class Location : INotifyPropertyChanging, INotifyPropertyChanged 
{  
    public int id;  
    public System.Nullable<int> idLocation;  
    public string brandingName;  
    public System.Data.Linq.Binary timeStamp;  
    public EntitySet<LocationZipCode> LocationZipCodes; 
} 

public partial class LocationZipCode : INotifyPropertyChanging, INotifyPropertyChanged 
{ 
    public string zipcode;  
    public string state;   
    public int idLocationDetail;   
    public int id;  
    public System.Data.Linq.Binary timeStamp;  
    public EntityRef<Location> Location; 
} 

...いくつかのLINQからSQLへのエンティティを持っています。

Locationドメインモデルは、プレゼンテーションレイヤーが消費するビューモデルにマッピングされ、最終的にドメインモデルLocationにマッピングされた変更されたビューモデルエンティティに返されます。そこからエンティティを更新し、変更を保存します。ここで

public class ProgramZipCodeManagerHandler : IHttpHandler { 
    private LocationsZipCodeUnitOfWork _locationsZipCodeUnitOfWork = new LocationsZipCodeUnitOfWork(); 

    public void ProcessRequest(HttpContext context) { 
     if (context.Request.HttpMethod == "POST") { 
      string json = Json.getFromInputStream(context.Request.InputStream); 

      if (!string.IsNullOrEmpty(json)) { 
       Location newLocation = Json.deserialize<Location>(json); 
       if (newLocation != null) { 
        //this maps the location view model from the client to the location domain model 
        var newDomainLocation = new Mapper<Location, DomainLocation>(new DomainLocationMapTemplate()).map(newLocation); 

        if (newDomainLocation.id == 0) 
         _locationsZipCodeUnitOfWork.locationRepository.insert(newDomainLocation); 
        else 
         _locationsZipCodeUnitOfWork.locationRepository.update(newDomainLocation); 

        _locationsZipCodeUnitOfWork.saveChanges(ConflictMode.ContinueOnConflict); 

        var viewModel = new Mapper<DomainLocation, Location>(new LocationMapTemplate()).map(newDomainLocation); 
        context.Response.ContentType = "application/json"; 
        context.Response.Write(Json.serialize(viewModel); 
       } 
      } 
     }  
    } 
} 

locationRepository内の更新方法であって:

protected System.Data.Linq.Table<T> _table; 

public void update(T entity) { 
    _table.Attach(entity, true); 
    _context.Refresh(RefreshMode.KeepCurrentValues, entity); 
} 

public void update(T newEntity, T oldEntity) { 
    _table.Attach(newEntity, oldEntity); 
    _context.Refresh(RefreshMode.KeepCurrentValues, newEntity); 
} 

私が直接更新されているLocationエンティティが、子コレクション(public EntitySet<LocationZipCode> LocationZipCodes)に関連付けられたすべてのレコードがあることがわかります。ここハンドラです更新されていません。

更新が必要な子EntitySetを持つ切断されたエンティティを更新する明確な方法がありますか?つまり、別のエンティティのコレクションを持つ分離されたエンティティがあります。そのコレクションは変更されており、データベース内のコレクションを更新する必要があります。

+0

子コレクションのエントリにそれぞれのIDがありますか? – rhughes

+0

はい彼らは自分のIDを持っています – bflemi3

答えて

2

いいえ..できません。

オブジェクトの接続と切り離しは、使用するオブジェクトごとに行われ、関連するオブジェクト(エンティティ)には影響しません。

あなたがここからさらに情報を読み取ることができます。
Attaching and Detaching Objects

は、オブジェクトAを1000個の値で満たされているコレクションBに関連している状況を考えてみましょう。 あなたはAを切り離していくつかのリモート処理に送ります - AはB関係でヌルで送信され、今度はAがあなたのプログラムに戻されます--ABヌルがリモート処理の結果であるか、すでにヌルでリモート処理に与えられていました。

この回答で投稿されたリンクでは、スクロールダウンして、慎重に「
」というタイトルのセクションを読んでください。

+0

私はhttp://helq2sqleb.codeplex.com/を探しているように見えるこのヘルパークラスを見つけました。あなたは正しいですが、非常にイライラ – bflemi3

0

私はあなたの質問を理解していませんが、ここに行く...おそらくエンティティをコンテキストなどに再接続する次のエンティティオブジェクト拡張のようなものは、エンティティをオブジェクトコンテキストに再接続し、エンティティ状態を適切に設定することによって機能します。

/// <summary> 
    /// AttachEntityToObjectContext attaches an EntityObject to an ObjectContext 
    /// </summary> 
    /// <param name="entityWithRelationships">An EntityObject that has relationships</param> 
    /// <param name="newContext">The ObjectContext to attach the entity to</param> 
    /// <returns>True if the entity has relationships (and therefore the method could succeed). Otherwise false.</returns> 
    /// <remarks>Objects are retrieved using one ObjectContext, stored in ViewState and then 
    /// an attempt to save them is then made. The save attempt does not save the object. This is because it is a different context which is saving the object. 
    /// So the object needs to be detached from its old context, added to the new context and have its EntityState maintained so that it gets saved.</remarks> 
    public static bool AttachEntityToObjectContext(this IEntityWithRelationships entityWithRelationships, ObjectContext newContext) 
    { 
     EntityObject entity = entityWithRelationships as EntityObject; 
     if (entity == null) 
     { 
      return false; 
     } 

     if (entity.EntityState != EntityState.Detached) 
     { 
      ObjectContext oldContext = entity.GetContext(); 
      if (oldContext == null) 
      { 
       return false; 
      } 

      if (oldContext != newContext) 
      { 
       EntityState oldEntityState = entity.EntityState; 
       oldContext.Detach(entity); 
       newContext.Attach(entity); 
       newContext.ObjectStateManager.ChangeObjectState(entity, oldEntityState); 
      } 
     } 

     return true; 
    } 

    /// <summary> 
    /// GetContext gets the ObjectContext currently associated with an entity 
    /// </summary> 
    /// <param name="entity">An EntityObject</param> 
    /// <returns>The ObjectContext which the entity is currently attached to</returns> 
    private static ObjectContext GetContext(this IEntityWithRelationships entity) 
    { 
     if (entity == null) 
     { 
      throw new ArgumentNullException("entity"); 
     } 

     var relationshipManager = entity.RelationshipManager; 

     var relatedEnd = relationshipManager.GetAllRelatedEnds().FirstOrDefault(); 

     if (relatedEnd == null) 
     { 
      // No relationships found 
      return null; 
     } 

     var query = relatedEnd.CreateSourceQuery() as ObjectQuery; 

     if (query == null) 
     { 
      // The Entity is Detached 
      return null; 
     } 

     return query.Context; 
    } 
+0

私は私の問題を反映してうまくいけば私の質問を更新しました。 – bflemi3

+0

linq-to-sqlコンテキストにはデタッチメソッドがありません。これはEFのためですか? – bflemi3

+0

はい、それはL2Eですが、私はこのような「何か」を言っていましたが、正しい方向に向けることを望んでいます。このコードを使用して、ビュー内のキャッシュに格納されているエンティティを現在のコンテキストに再接続します。 –

関連する問題