0

为什么这种方法似乎不起作用?标准方法应该是什么?

[Database(Name = "Test")]
[Table(Name = "Order")]
public class Order
{
    [Column(Name = "ID", IsPrimaryKey = true)]
    public int ID { get; set; }

    [Column(Name = "OrderDate")]
    public DateTime OrderDate { get; set; }


    public static Order Get(int id)
    {
        Order item = null;

        try
        {
            DataContext dc = new DataContext(@"Data Source=.\sqlexpress;Initial Catalog=Test;Integrated Security=True");

            var items = from order
                        in dc.GetTable<Order>()
                        where order.ID == id
                        select order;

            item = items.FirstOrDefault<Order>();

            dc.Dispose();
        }
        catch (Exception ex)
        {
            item = null;

            throw ex;
        }

        return item;
    }

    public bool Delete()
    {
        bool success = false;

        try
        {
            DataContext dc = new DataContext(@"Data Source=.\sqlexpress;Initial Catalog=Test;Integrated Security=True");

            dc.GetTable<Order>().DeleteOnSubmit(this);

            success = true;
        }
        catch (Exception ex)
        {
            success = false;

            throw ex;
        }

        return success;
    }
}

class Program
{
    static void Main(string[] args)
    {            
        Order order = Order.Get(1);

        order.Delete();

        Console.ReadLine();
    }
}

此代码生成以下异常:

InvalidOperationException : "Cannot remove an entity that has not been attached."

我还尝试了以下方法:

DataContext dc = new DataContext(@"Data Source=(local)\sqlexpress;Initial Catalog=Relationships_Test;user=;password=;Integrated Security=True");

dc.GetTable<Order>().Attach(this);
dc.GetTable<Order>().DeleteOnSubmit(this);

它也没有用。

4

4 回答 4

3

您正在创建一个新DataContextDelete()方法,该方法不“知道”Order您要删除的对象。(“实体未附加”)

Order对象附加到第DataContext一个。

编辑
您可能必须调用item.Detach()您的Get(...)方法才能成功调用dc.Orders.Attach(...)Delete方法。

编辑 2
哦,顺便说一句:你的catch处理程序有点没用 - 它们基本上什么都不做,因为当重新抛出异常时不会使用返回值。在调用代码中捕获异常 - 无需返回success标志或设置itemnull...

编辑 3
当然,正如克里斯所说,你必须打电话SubmitChanges才能真正做点什么。但是,我假设您已经这样做了,只是因为您遇到了异常而被问到。

于 2009-12-29T14:55:49.713 回答
1

即使您将它附加到上下文,您也必须调用DataContext.SubmitChanges()才能实际执行命令。

如果你要调用 DataContext.Dispose(),你应该从try/catch/finally 子句的finally块开始。您可能应该使用using 语句,而不是手动调用它。

于 2009-12-29T15:14:43.773 回答
1

如果您有一个在 DataContext 的上下文中创建的对象(在本例中为订单项),则一旦您 Dispose DataContext,该对象就会成为孤立对象。

要从数据库中删除孤立对象,您需要不释放原始 DataContext 或以某种方式将对象附加到新 DataContext(这可能很棘手)。

The easiest way to deal with this is to new the DataContext in your Main method and then Dispose the DataContext at the end of the main method (that is a standard pattern).

于 2009-12-29T15:50:35.260 回答
0

我认为让您的业务对象尽可能不了解持久性机制更为标准。查看 LINQ to SQL 设计器创建其实体的方式。对象本身不知道 DataContext。它们具有允许数据上下文添加更改通知机制的钩子和其他钩子以允许实体为其生命周期中发生的特定事件添加代码(创建,验证,...)。它们也被创建为部分类实现,因此您可以根据需要添加更多代码并实现提供的部分方法挂钩。

更好、更标准的方法是使用设计器和设计器生成的类作为您的 ORM,通过部分类实现添加更多代码。或者,您可以在生成的数据上下文之上分层存储库模式(或此处),甚至选择不同的 ORM(例如nHibernate)。

于 2009-12-29T15:19:37.087 回答