ho le seguenti entités/tabelle:WP8 e LINQ to SQL con uno-a-molti relazione: SubmitChanges() rimuove entità sbagliato
Board
: Una scheda può avere molti perniPin
: One pin è assegnato a una scheda. Questa entità è astratta e ha figli con diverse implementazioni. Tutte bambino appartenenti all'entità perno genitore conInheritanceMapping
e verranno salvate nella tabella perno e distinto da unDiscriminator column
TaskPin
: Questo è uno implementazioni figlio di perno. Può avere molti compiti.
Task
: Un compito viene assegnato a uno TaskPin
Ecco il codice per rendere la mia struttura più chiara:
[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()
{
}
}
creo un TaskPin
e assegnarlo a una tavola. Quindi creo due Task e li assegno alla TaskPin. Questo funziona bene. Il problema occurrs quando provo a uno o più Tasks
dalla TaskPin
:
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);
}
}
Se chiamo allora SubmitChanges()
sul mio DataContext
oggetto, si imposterà il Board property
del TaskPin (ereditato da Pin) a 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();
}
mi aspetto che il Task
saranno cancellati a causa DeleteOnNull
è impostato su vero, ma non so il motivo per cui il Board property
del perno è anche impostato su null
che si tradurrà in un NullPointerExceptio
o che il Pin viene eliminato anche .
Ho fatto una ricerca su google su questo argomento ma non trovo nulla che risolva il mio problema. Un'alternativa potrebbe essere quella di impedire il blocco delle proprietà della scheda e chiamare manualmente DeleteOnSubmit()
per Attività.
Come si utilizza il datacontext: una volta creato o ricreato ogni volta? Conoscete sql profiler? Sembra che tu abbia due transazioni e io possa essere il visualizzatore con profiler. –
Il tuo 'changeSet' contiene un riferimento non nullo a' Board'? Sospetto che il tuo oggetto grafico non venga caricato a causa di altri fattori. – Mrchief
@Mrchief cosa intendi con il grafo degli oggetti? Il set di modifiche contiene una voce per la TaskPin da eliminare. –