Программа, приведенная ниже, завершается с ошибкой.Он использует то, что должно быть довольно распространенным вариантом использования, поэтому маловероятно, что это ошибка в платформе (LINQ to SQL не совсем новый).
Может кто-нибудь подсказать, что я делаю неправильно?
Я знаю, что всегда есть возможность сбросить текущий DataContext и продолжить с новым, но в моем сценарии это было бы слишком расточительно (так как это заставило бы меня перезагрузить тысячи объектов).
(я не использую конструктор LINQ to SQL, потому что этот код в какой-то момент должен также работать на WP7.1).
using System;
using System.Linq;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.IO;
sealed class Context : DataContext
{
internal Context(string databaseFile) : base(databaseFile)
{
this.Customers = this.GetTable<Customer>();
this.Orders = this.GetTable<Order>();
this.OrderDetails = this.GetTable<OrderDetail>();
}
internal readonly Table<Customer> Customers;
internal readonly Table<Order> Orders;
internal readonly Table<OrderDetail> OrderDetails;
}
[Table]
sealed class Customer
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
private int Id { get; set; }
[Column]
private int Whatever { get; set; }
private EntitySet<Order> orders;
public Customer()
{
this.orders = new EntitySet<Order>(
order => order.Associate(this), order => order.Associate(null));
}
[Association(Storage = "orders", OtherKey = "CustomerId")]
internal EntitySet<Order> Orders { get { return this.orders; } }
}
[Table]
sealed class Order
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
private int Id { get; set; }
[Column]
private int CustomerId { get; set; }
private EntityRef<Customer> customer;
private readonly EntitySet<OrderDetail> orderDetails;
public Order()
{
this.orderDetails = new EntitySet<OrderDetail>(
detail => detail.Associate(this),
detail => detail.Associate(null));
}
internal void Associate(Customer newCustomer) { this.customer.Entity = newCustomer; }
[Association(Storage = "customer", ThisKey = "CustomerId", IsForeignKey = true)]
internal Customer Customer { get { return this.customer.Entity; } }
[Association(Storage = "orderDetails", OtherKey = "OrderId")]
internal EntitySet<OrderDetail> OrderDetails { get { return this.orderDetails; } }
}
[Table]
sealed class OrderDetail
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
private int Id { get; set; }
[Column]
private int OrderId { get; set; }
private EntityRef<Order> order;
internal void Associate(Order newOrder) { this.order.Entity = newOrder; }
[Association(Storage = "order", ThisKey = "OrderId", IsForeignKey = true)]
internal Order Order { get { return this.order.Entity; } }
}
class Program
{
static void Main()
{
var exeDirectory = Path.GetDirectoryName(
typeof(Program).Assembly.ManifestModule.FullyQualifiedName);
var dataDirectory = Path.Combine(exeDirectory, Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(dataDirectory);
var dataFile = Path.Combine(dataDirectory, "DB.sdf");
using (var context = new Context(dataFile))
{
context.CreateDatabase();
// Insert a Customer
var customer = new Customer();
context.Customers.InsertOnSubmit(customer);
context.SubmitChanges();
// Insert the first Order
var order1 = new Order();
customer.Orders.Add(order1);
context.SubmitChanges();
// Insert the first OrderDetail
var detail1 = new OrderDetail();
order1.OrderDetails.Add(detail1);
context.SubmitChanges();
// Insert the second OrderDetail
order1.OrderDetails.Add(new OrderDetail());
context.SubmitChanges();
// Delete the first OrderDetail
context.OrderDetails.DeleteOnSubmit(detail1);
order1.OrderDetails.Remove(detail1);
// Everything works as expected up to this point. For all the
// changes above, context.GetChangeSet() has always been
// showing the expected changes.
// This succeeds. As expected, we now have a single Customer
// with a single Order and a single OrderDetail in the database.
context.SubmitChanges();
// Add a second Order
var order2 = new Order();
customer.Orders.Add(order2);
// The following fails with an InvalidOperationException with
// the message:
// An attempt was made to remove a relationship between a
// Customer and a Order. However, one of the relationship's
// foreign keys (Order.CustomerId) cannot be set to null.
//
// It is absolutely unclear why an attempt is made to
// delete/remove an Order. In the code above we're only
// ever deleting an OrderDetail, *not* an Order.
context.SubmitChanges();
}
}
}