我有以下实体/表:
Board
: 一 block 板可以有很多pinPin
:一个引脚分配给一个板。该实体是抽象的,并且确实有具有不同实现的子实体。属于具有InheritanceMapping
的父 pin 实体的所有子实体将被保存到 pin 表中并由Discriminator 列
区分TaskPin
:这是 pin 的一个子实现。它可以有很多任务。
Task
:一个任务分配给一个TaskPin
这里有一些代码可以让我的结构更清晰:
[Table]
public class Board : ModelBase
{
private int _boardId;
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity"
,CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int BoardId
{
get { return _boardId; }
set { SetProperty(ref _boardId, value); }
}
private EntitySet<Pin> _pins;
[Association(Storage = "_pins", OtherKey = "_boardId"
,ThisKey = "BoardId", DeleteRule = "CASCADE")]
public EntitySet<Pin> Pins
{
get { return _pins; }
set { _pins.Assign(value); }
}
public Board()
{
_pins = new EntitySet<Pin>(new Action<Pin>(this.addPin)
,new Action<Pin>(this.removePin));
}
private void addPin(Pin pin)
{
NotifyPropertyChanging("Pin");
pin.Board = this;
}
private void removePin(Pin pin)
{
NotifyPropertyChanging("Pin");
pin.Board = null;
}
}
[Table]
[InheritanceMapping(Code = PinType.TaskPin, Type = typeof(TaskPin)
,IsDefault = true)]
public abstract class Pin : ModelBase
{
private int _pinId;
[Column(IsPrimaryKey = true, IsDbGenerated = true
,DbType = "INT NOT NULL Identity", AutoSync = AutoSync.OnInsert)]
public int PinId
{
get { return _pinId; }
set { SetProperty(ref _pinId, value); }
}
[Column]
internal int _boardId;
private EntityRef<Board> _board;
[Association(Storage = "_board", ThisKey = "_boardId"
,OtherKey = "BoardId", IsForeignKey = true, DeleteOnNull = true)]
public Board Board
{
get { return _board.Entity; }
set
{
if (SetProperty(ref _board, value) != null)
{
_boardId = value.BoardId;
}
}
}
[Column(IsDiscriminator = true)]
public PinType Type { get; set; }
public Pin()
{
}
}
public class TaskPin : Pin
{
private EntitySet<Task> _tasks;
[Association(Storage = "_tasks", OtherKey = "_pinId"
,ThisKey = "PinId", DeleteRule = "CASCADE")]
public EntitySet<Task> Tasks
{
get { return _tasks; }
set { _tasks.Assign(value); }
}
public TaskPin()
{
_tasks = new EntitySet<Task>(new Action<Task>(this.addTask)
,new Action<Task>(this.removeTask));
}
private void addTask(Task task)
{
NotifyPropertyChanging("Task");
task.Pin = this;
}
private void removeTask(Task task)
{
NotifyPropertyChanging("Task");
task.Pin = null;
}
}
[Table]
public class Task : ModelBase
{
private int _taskId;
[Column(IsPrimaryKey = true, IsDbGenerated = true
,DbType = "INT NOT NULL Identity"
,CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int TaskId
{
get { return _taskId; }
set { SetProperty(ref _taskId, value); }
}
[Column]
internal int _pinId;
private EntityRef<Pin> _pin;
[Association(Storage = "_pin", ThisKey = "_pinId"
,OtherKey = "PinId"
,IsForeignKey = true
,DeleteOnNull=true)]
public Pin Pin
{
get { return _pin.Entity; }
set
{
if (SetProperty(ref _pin, value) != null)
{
_pinId = value.PinId;
}
}
}
public Task()
{
}
}
我创建了一个 TaskPin
并将其分配给一个板。然后我创建两个任务并将它们分配给 TaskPin。这确实很好用。当我尝试从 TaskPin
执行一个或多个 Tasks
时出现问题:
private void OnDeleteTasks(object sender, EventArgs e)
{
TaskPin taskPin = pin as TaskPin;
var completedTasks = taskPin.Tasks
.Where(x => x.IsDone == true)
.ToList();
foreach (var task in completedTasks)
{
taskPin.Tasks.Remove(task);
}
}
如果我在 DataContext
对象上调用 SubmitChanges()
,它将设置 TaskPin(继承自 Pin)的 Board 属性
为 null
。
public void Save(Pin pin)
{
// This is empty so no modified members are identified => Correct
var modifiedMembers = db.Pins.GetModifiedMembers(pin);
// Contains just one entry for the deleted Task entity => Correct
var changeSet = db.GetChangeSet();
// This call will immediately set Board property of Pin to null => Wrong!
db.SubmitChanges();
}
我预计 Task
会被删除,因为 DeleteOnNull
设置为 true 但我不知道为什么 Board property
的 Pin也设置为 null
,这将导致 NullPointerExceptio
或 Pin 也被删除。
我对这个主题进行了谷歌搜索,但没有找到任何可以解决我的问题的东西。一种替代方法是防止 Board 属性归零并手动为任务调用 DeleteOnSubmit()
。
最佳答案
在我看来,这种行为是有意为之的。
如果您查看 Task 类中的 Pin 属性,它被设置为在 Null (DeleteOnNull = true) 时删除,然后Task 中的 Pin 将按照 TaskPin 类中的 removeTask() 删除。然后查看Board 类中的removePin() 方法,它将Pin 的Board 设置为null。然后查看Pin 类中的Board 属性,DeleteOnNull 设置为true 这将从Board 中删除strong>Pin 设置为 null 时的实例。
关于c# - WP8 和 Linq to SQL 具有一对多关系 : SubmitChanges() removes wrong entity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26225103/