Хорошо, я пытался преобразовать свою модель для использования LINQ, но не хотел выбрасывать мои текущие DTO и их интерфейсы, которые разбросаны по домену.
Мне удалось найти этот пост в блоге, который довольно хорошо описал процесс:
Достижение POCO в LINQ To SQL
Мне удалось получить извлечение записей для объектов, работающих должным образом, однако, из-за вложенной природы моей модели, я не могу заставить дополнение работать с дочерними объектами. То есть, если я создаю дочерний объект и устанавливаю ссылку на нужный родительский объект, LINQ to SQL по-прежнему выдает исключение, указывающее, что ссылка дочернего элемента на родительский объект является нулевой. Если я пытаюсь добавить простой старый родительский объект, это успешно, но добавление дочерних объектов непосредственно терпит неудачу
Вот мой провальный тест:
[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: была предпринята попытка удалить связь между рынком и выбором. Однако один из внешних ключей отношения (Selection.MID) не может быть установлен равным нулю.
Соответствующие части 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;
и *; 1024 *
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>
Так, кто-нибудь может указать мне правильное направление? Я искал часы ...
Edit:
Вот моя трассировка стека для моего теста:
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"
для внешнего ключа Selections в сопоставлении XML устранена ошибка внешнего ключа, но теперь я получаю нулевую ссылку на один из дочерних объектов Selections, говоря, что его ссылка на Selection является нулевой, даже если Selection инициализируется ни с одним его переменные установлены (вне внешних ключей). Я даже пытался создать дочерний объект и правильно установить его ссылки, но все еще получаю эту ошибку:
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 рынок имеет много выборов) и т. Д. И т. Д.