gpt4 book ai didi

c# - WP8 和 Linq to SQL 具有一对多关系 : SubmitChanges() removes wrong entity

转载 作者:太空狗 更新时间:2023-10-29 22:00:51 25 4
gpt4 key购买 nike

我有以下实体/表:

  • Board: 一 block 板可以有很多pin
  • Pin:一个引脚分配给一个板。该实体是抽象的,并且确实有具有不同实现的子实体。属于具有 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() 方法,它将PinBoard 设置为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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com