さて、モデルを LINQ を使用するように変換しようとしましたが、現在の DTO と、ドメイン全体に散らばっているインターフェイスを破棄したくありませんでした。
プロセスの概要を非常にうまくまとめたこのブログ投稿を見つけることができました。
オブジェクトへのレコードの取得は正常に機能していますが、モデルのネストされた性質により、子オブジェクトの追加機能を取得できないようです。つまり、子オブジェクトを作成し、目的の親オブジェクトへの参照を設定すると、LINQ to SQL は、親への子の参照が null であることを示す例外をスローします。単純な古い親オブジェクトを追加しようとすると成功しますが、子オブジェクトを直接追加すると失敗します
これが私の失敗したテストです:
[Test]
public void AddSelectionShouldAddSelectionToMarket()
{
Market market = (Market) new Repository().GetMarket(1);
Selection selection = new Selection();
selection.Market = market;
new Repository().AddSelection(selection);
Assert.IsTrue(selection.SID > 0);
}
エラーメッセージは次のとおりです。
System.InvalidOperationException: Market と Selection の間の関係を削除しようとしました。ただし、リレーションシップの外部キー (Selection.MID) の 1 つを null に設定することはできません。
2 つのオブジェクトの関連部分:
[DataContract]
public class Selection : ISelection
{
private int mID;
[DataMember]
public int MID
{
get { return this.mID; }
set { this.mID = value; }
}
private Market market;
[DataMember]
public Market Market
{
get { return this.market; }
set
{
this.market = value;
this.mID = value.MID;
}
}
}
[DataContract]
public class Market : IMarket
{
private int mID;
[DataMember]
public int MID
{
get { return this.mID; }
protected set { this.mID = value; }
}
private List<Selection> selections;
[DataMember]
public List<Selection> Selections
{
get { return this.selections; }
set
{
this.selections = value;
// For LINQ
foreach (Selection selection in selections)
{
selection.MID = mID;
selection.Market = this;
}
}
}
}
私のDAコード:
MarketsDataContext context = new MarketsDataContext();
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Selection>(s => s.Prices);
options.LoadWith<Market>(m => m.Selections);
context.LoadOptions = options;
return context;
と;
public void AddSelection(ISelection selection)
{
using (MarketsDataContext context = MarketsDataContext.GetContext())
{
context.Selections.InsertOnSubmit((Selection) selection);
context.SubmitChanges();
}
}
そして最後に私の XML マッピング:
<Table Name="dbo.Markets" Member="Markets">
<Type Name="Market">
<Column Name="MID" Member="MID" Storage="mID" DbType="Int NOT NULL" IsPrimaryKey="true" IsDbGenerated="true" AutoSync="OnInsert" />
<Association Name="FK_Market-Selections" Member="Selections" Storage="selections" ThisKey="MID" OtherKey="MID" DeleteRule="NO ACTION" />
</Type>
</Table>
<Table Name="dbo.Selections" Member="Selections">
<Type Name="Selection">
<Column Name="SID" Member="SID" Storage="sID" DbType="Int NOT NULL" IsPrimaryKey="true" IsDbGenerated="true" AutoSync="OnInsert" />
<Column Name="MID" Member="MID" Storage="mID" DbType="Int NOT NULL" />
<Association Name="FK_Market-Selections" Member="Market" Storage="market" ThisKey="MID" OtherKey="MID" IsForeignKey="true" />
</Type>
</Table>
それで、誰かが私を正しい方向に向けることができますか?私は何時間も探していました...
編集:
テスト失敗のスタックトレースは次のとおりです。
at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.SynchDependentData()
at System.Data.Linq.ChangeProcessor.ValidateAll(IEnumerable`1 list)
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at BetMax.DataModel.Repository.AddSelection(ISelection selection) in Repository.cs: line 68
at BetMax.DataModel.Test.ModelTest.AddSelectionShouldAddSelectionToMarket() in ModelTest.cs: line 65
そして私の GetMarket メソッド:
public IMarket GetMarket(int MID)
{
Market market;
using (MarketsDataContext context = MarketsDataContext.GetContext())
{
market = context.Markets.Single(m => m.MID == MID);
}
return market;
}
編集2:
さて、追加
DeleteOnNull="true"
XML マッピングの外部キーを選択すると、外部キー エラーが削除されましたが、現在、選択の子オブジェクトの 1 つで null 参照を取得しています。選択が変数セットなしで初期化されているにもかかわらず、選択への参照が null であると言っています。 (外部キーの外)。私は子オブジェクトを作成しようとしましたが、その参照を正しく設定しましたが、まだこのエラーが発生しています:
System.NullReferenceException: Object reference not set to an instance of an object.
at BetMax.DTO.Price.set_Selection(Selection value) in Price.cs: line 25
at System.Data.Linq.Mapping.PropertyAccessor.Accessor`3.SetValue(ref T instance, V value)
at System.Data.Linq.Mapping.MetaAccessor`2.SetBoxedValue(ref Object instance, Object value)
at System.Data.Linq.ChangeProcessor.ClearForeignKeysHelper(MetaAssociation assoc, Object trackedInstance)
at System.Data.Linq.ChangeProcessor.ClearForeignKeyReferences(TrackedObject to)
at System.Data.Linq.ChangeProcessor.PostProcessUpdates(List`1 insertedItems, List`1 deletedItems)
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at BetMax.DataModel.Repository.AddSelection(ISelection selection) in Repository.cs: line 68
at BetMax.DataModel.Test.ModelTest.AddSelectionShouldAddSelectionToMarket() in ModelTest.cs: line 69
価格は別のオブジェクトであり、その選択が市場に関連するのと同じように構築されます (1 つの選択には多くの価格があり、1 つの市場には多くの選択があります) など。