首先让我解释一下,我完全理解为什么InvalidOperationException会抛出这个,我只是在寻找一种方法来避免它被抛出。System.Linq.Enumerable.SingleOrDefault()我可以在 Visual Studio 2010 调用堆栈窗口中看到一个调用。但是,调用是在外部Linq2Sql代码中,所以我无权更改它。
(抱歉,您可能需要放大才能正确查看此图像)
在我有权访问的应用程序文件中找到执行外部之前的最后一次内部代码调用dbml.designer.cs,但仍然无法编辑,因为它会自动更新并丢失自定义更改。它位于Linq2Sql应用程序中使用的其中一个数据库表的 () 属性设置器中,看起来问题是由对_DbAudioTrackContributors.Entity对象的调用引起的:
public DbAudioTrackContributor DbAudioTrackContributors
{
get
{
return this._DbAudioTrackContributors.Entity;
}
set
{
// This is the last internal line before the Exception
DbAudioTrackContributor previousValue = this._DbAudioTrackContributors.Entity;
// Execution never reaches here
if (((previousValue != value) ||
(this._DbAudioTrackContributors.HasLoadedOrAssignedValue == false)))
{
this.SendPropertyChanging();
if ((previousValue != null))
{
this._DbAudioTrackContributors.Entity = null;
previousValue.DbAudioTrack = null;
}
this._DbAudioTrackContributors.Entity = value;
if ((value != null))
{
value.DbAudioTrack = this;
}
this.SendPropertyChanged("DbAudioTrackContributors");
}
}
}
如果有人有办法向我提供EntityRef<TEntity>结构(甚至只是Entity属性)的内部代码,这可能会帮助我找出导致问题的原因。
在抛出之前我自己的代码的最后一行InvalidOperationException是调用dataContext.SubmitChanges():
public int UpdateAudioTrack(AudioTrack audioTrack)
{
using (TransactionScope transactionScope = new TransactionScope())
{
using (MidasDataContext dataContext = DataContext)
{
DbAudioTrack dbAudioTrack = dataContext.DbAudioTracks.Where(
g => g.Id == audioTrack.Id).FirstOrDefault();
if (dbAudioTrack == null) return -1;
CopyToDbAudioTrack(audioTrack, dbAudioTrack);
UpdateAudioTrackContributors(dataContext, audioTrack);
// This is the last line of my code before the Exception
dataContext.SubmitChanges(ConflictMode.FailOnFirstConflict);
// Execution never reaches here
transactionScope.Complete();
return 0;
}
}
}
该CopyToDbAudioTrack方法只是将对象中的所有属性值复制AudioTrack到Linq2Sql生成的DbAudioTrack对象中,该UpdateAudioTrackContributors方法如下所示。
private void UpdateAudioTrackContributors(MidasDataContext dataContext, AudioTrack audioTrack)
{
DataList<Label> labels = new DataList<Label>(
audioTrack.Labels.Except(audioTrack.OriginalState.Labels));
if (labels.Count > 0) AddAudioTrackContributors(dataContext, audioTrack, labels);
labels = new DataList<Label>(audioTrack.OriginalState.Labels.Except(audioTrack.Labels));
if (labels.Count > 0) DeleteAudioTrackContributors(dataContext, audioTrack, labels);
}
此方法只是查找已更改的对象,然后在数据库表Label中添加或删除它们。AudioTrackContributors该表似乎是问题的根源,因为如果注释掉此代码,它就会消失。但是,这种方法正确地选择了要添加或删除的对象,所以我仍然感到困惑。该AddAudioTrackContributors方法基本上调用如下所示的代码,DeleteAudioTrackContributors代码如下所示:
List<DbAudioTrackContributor> dbAudioTrackContributors = new List<DbAudioTrackContributor>();
foreach (T dataListEntry in dataList)
{
DbAudioTrackContributor dbAudioTrackContributor = new DbAudioTrackContributor();
CopyToDbAudioTrackContributor(audioTrack, dataListEntry, dbAudioTrackContributor, contributorType);
dbAudioTrackContributors.Add(dbAudioTrackContributor);
}
dataContext.DbAudioTrackContributors.InsertAllOnSubmit(dbAudioTrackContributors);
DeleteAudioTrackContributors:
List<DbAudioTrackContributor> dbAudioTrackContributors = new List<DbAudioTrackContributor>();
foreach (T dataListEntry in dataList)
{
DbAudioTrackContributor dbAudioTrackContributor = dataContext.DbAudioTrackContributors.Where(d => d.DataListId == dataListEntry.Id && d.AudioTrackId == audioTrack.Id).FirstOrDefault();
if (dbAudioTrackContributor != null) dbAudioTrackContributors.Add(dbAudioTrackContributor);
}
dataContext.DbAudioTrackContributors.DeleteAllOnSubmit(dbAudioTrackContributors);
同样,在执行期间单步执行代码表明上述代码也正确选择了要删除的正确对象。由于我在我的代码中看不到任何问题,因此我不知道下一步该往哪里看。
如果有人对如何进行有任何想法,我会很高兴听到他们的声音。提前谢谢了。