[英]Updating disconnected entity that has child entities in linq to sql
在n層應用程序中,linq-to-sql似乎沒有明確的解決方案來更新具有子EntitySet的斷開連接的實體。
我有一些linq-to-sql實體......
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;
}
因此, Location
實體將具有LocationZipCodes
的EntitySet
。
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
( public EntitySet<LocationZipCode> LocationZipCodes
)沒有被更新。
是否有明確的方法來更新具有子EntitySet的斷開連接的實體,該實體也需要更新? 換句話說,我有一個分離的實體,它有另一個實體的集合。 該集合已更改,我需要在數據庫中更新它。
不......你做不到。
根據您使用的對象附加和分離對象,不會影響相關對象(實體)。
您可以從這里閱讀更多信息:
附加和分離對象
考慮一種情況,其中對象A與集合B相關,集合B填充有1000個值。 您分離A並將其發送到某個遠程處理 - A在B關系中以null發送..現在A被帶回到您的程序 - 無法知道AB null是遠程處理的結果或者是它已經給null了遠程處理。
在使用此答案發布的鏈接中 - 請向下滾動以仔細閱讀標題為:
分離對象的注意事項。
我不太清楚我理解你的問題,但是這里...類似下面的實體對象擴展,也許你將實體重新附加到上下文等,將通過將實體重新附加到對象上下文並適當地設置entitystate來工作。
/// <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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.