这是我第一次尝试使用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&lt;&gt;?
基本上,我认为我应该可以使用编辑操作中的命令更新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行:设置{this._Stream2FieldTypes.Assign(value); }
第61行:}
第62行:
答案 0 :(得分:3)
在SaveStream
方法中,您可以像StreamID
一样设置StreamID = item.StreamID
属性。因为您有Stream ID,我希望您尝试更改现有的Stream
类。但是,在查看代码时,您将创建一个新代码。我认为您遇到的问题是由此造成的。
您应该做的是以下内容:
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;
}
干杯