![](/img/trans.png)
[英]How can I update a parent object that comes with child details in EntityFramework 6?
[英]In LINQtoSQL, how can I update child relationships by editing the parent model?
這是我第一次嘗試使用LINQtoSQL更新數據庫。 至少,如果您不計算我所遵循的教程,這將是我的第一篇。 不幸的是,我發現的教程只提供了更新單個表的功能。 我正在嘗試更新更為復雜的數據庫模型。
我有一個Stream
表:
[Table]
public class Stream
{
[HiddenInput(DisplayValue = false)]
[Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public long StreamID { get; set; }
/** Other columns removed for brevity **/
// relationship:
private EntitySet<Stream2FieldTypes> _Stream2FieldTypes;
[System.Data.Linq.Mapping.Association(Storage = "_Stream2FieldTypes", OtherKey = "StreamID")]
public EntitySet<Stream2FieldTypes> Stream2FieldTypes
{
get { return this._Stream2FieldTypes; }
set { this._Stream2FieldTypes.Assign(value); }
}
我有一個Stream2FieldTypes
表:
[Table]
public class Stream2FieldTypes
{
[Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public long s2fID { get; set; }
public long StreamID { get; set; } // FK
/** other columns removed for brevity **/
// relationship (one Stream2FieldTypes to many Streams)
private EntitySet<Stream> _Stream;
[Association(Storage = "_Stream", ThisKey = "StreamID")]
public EntitySet<Stream> Stream
{
get { return this._Stream; }
set { this._Stream.Assign(value); }
}
現在,我正在嘗試更新模型,以便可以將更新發送到存儲庫以保留到DataContext
。 我無法更新Stream.Stream2FieldTypes
因為get
設置為私有EntitySet
。
如何更新Stream.Stream2FieldTypes
的時候我不能改變Stream.Stream2FieldTypes
因為它是一個私有的EntitySet <>?
基本上,我認為我應該能夠通過在Edit Action中使用如下命令來更新Stream
和Stream2FieldTypes
表:
myRepository.SaveStream(stream);
我一直在嘗試做這樣的事情:
if (ModelState.IsValid)
{
// Convert StreamEditModel to Stream
var stream = new Genesis.Domain.Entities.Stream
{
StreamID = form.StreamID,
StreamUrl = form.StreamUrl,
StreamName = form.StreamName,
StreamBody = form.StreamBody,
StreamTitle = form.StreamTitle,
StreamKeywords = form.StreamKeywords,
StreamDescription = form.StreamDescription,
Stream2FieldTypes = new EntitySet<Stream2FieldTypes>()
};
// Loop to convert Stream2FieldTypes to Steam2FieldTypesEditModel
foreach (var item in form.Stream2FieldTypes)
{
var fieldTypeEntry = new Stream2FieldTypes
{
FieldTypeID = item.FieldTypeID,
s2fID = item.s2fID,
s2fIsRequired = item.s2fIsRequired,
s2fLabel = item.s2fLabel,
StreamID = item.StreamID,
};
stream.Stream2FieldTypes.Add(fieldTypeEntry); // Add to list
}
genesisRepository.SaveStream(stream);
return RedirectToAction("Index");
}
else
{
return View(form);
}
當我嘗試運行此代碼時,出現以下錯誤:
異常詳細信息:System.NullReferenceException:對象引用未設置為對象的實例。
源錯誤:
第58行:{
第59行:get {return this._Stream2FieldTypes; }
出現錯誤的行:第60行:set {this._Stream2FieldTypes.Assign(value); }
第61行:}
第62行:
在您的SaveStream
方法中,您可以像這樣設置StreamID
屬性: StreamID = item.StreamID
。 因為您具有Stream ID,所以我希望您嘗試更改現有的Stream
類。 但是,查看代碼時,您正在創建一個新代碼。 我認為您遇到的問題是由此引起的。
您應該執行以下操作:
EntitySet
內部,並將EntitySet
和EntityRef
公共)。 例如,我認為您的SaveStream
應該看起來更像下一個代碼。 如果仔細觀察,此代碼缺少以下行:
FieldTypeID = item.FieldTypeID
和 StreamID = form.StreamID
。 這是因為這根本行不通。 您需要首先從數據庫中檢索現有實體並進行更新。 您無法創建新對象,不能將其ID設置為數據庫中的現有記錄,並希望LINQ to SQL可以為您更新該記錄。 這不是LINQ to SQL的設計方式。
這是可能適合您的示例:
public void SaveStream(StreamEditModel stream)
{
if (!ModelState.IsValid)
{
return;
}
if (stream.Id == 0)
{
CreateStream(stream);
}
else
{
UpdateStream(stream);
}
}
private void CreateStream(StreamEditModel form)
{
var stream = new Stream();
FillStream(stream, form);
UpdateStream2FieldTypes(stream, form);
genesisRepository.SubmitChanges();
}
private void UpdateStream(StreamEditModel form)
{
var stream = genesisRepository.GetById(stream.StreamID);
FillStream(stream, form);
UpdateStream2FieldTypes(stream, form);
genesisRepository.SubmitChanges();
}
private void FillStream(Stream stream, StreamEditModel form)
{
stream.StreamUrl = form.StreamUrl;
stream.StreamName = form.StreamName;
stream.StreamBody = form.StreamBody;
stream.StreamTitle = form.StreamTitle;
stream.StreamKeywords = form.StreamKeywords;
stream.StreamDescription = form.StreamDescription;
}
private void UpdateStream2FieldTypes(Stream stream,
StreamEditModel form)
{
var typesToDelete =
from type in stream.Stream2FieldTypes
let ids = form.Stream2FieldTypes.Select(t => t.FieldTypeID)
where !ids.Contains(type.FieldTypeID)
select type;
genesisRepository.RemoveStream2FieldTypes(typesToDelete);
var typesToAdd =
from type in form.Stream2FieldTypes
where type.FieldTypeID == 0
select CreateStream2FieldTypes(type);
foreach (var typeToAdd in typesToAdd)
{
stream.Stream2FieldTypes.Add(typeToAdd);
}
var formTypesToUpdate =
from type in form.Stream2FieldTypes
where type.FieldTypeID != 0
select type;
foreach (var modelToUpdate in formTypesToUpdate)
{
var typeToUpdate = stream.Stream2FieldTypes.Single(
t => t.FieldTypeID == modelToUpdate.FieldTypeID);
FillStream2FieldTypes(typeToUpdate, typeToUpdate);
}
}
private static Stream2FieldTypes CreateStream2FieldTypes(
Stream2FieldTypesEditModel form)
{
var fieldType = new Stream2FieldTypes();
FillStream2FieldTypes(fieldType, form);
return fieldType;
}
private static void FillStream2FieldTypes(
Stream2FieldTypes type,
Stream2FieldTypesEditModel item)
{
type.s2fID = item.s2fID;
type.s2fIsRequired = item.s2fIsRequired;
type.s2fLabel = item.s2fLabel;
}
干杯
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.