通过Linq更新数据库到SQL不起作用

时间:2014-07-17 13:52:21

标签: c# asp.net linq-to-sql

我正在开发一个C#ASP.NET应用程序,我正在从数据库中检索一些数据,抛出一个表单,当我点击Save时,我希望它将我的更改保存在数据库中。 / p>

我正在使用Linq to SQL。最后,下面的代码调用方法ClienteBusiness.SalvarAlteracoes(cliente),顺便说一下,只调用ClienteData.SalvarAlteracoes(cliente)方法。

protected void Salvar()
{
    TB_CLIENTE_CLI cliente = new TB_CLIENTE_CLI();

    int idEstado = 0;
    int idCidade = 0;
    if (!Int32.TryParse(ddlEstado.SelectedValue, out idEstado))
    {
        return;
    }
    if (!Int32.TryParse(Request.Form[ddlCidade.UniqueID], out idCidade))
    {
        return;
    }

    cliente.TXT_RAZAOSOCIAL_CLI = txtRazaoSocial.Text;
    cliente.TXT_NOMEFANTASIA_CLI = txtNomeFantasia.Text;
    cliente.TXT_CNPJ_CLI = txtCNPJ.Text;
    cliente.TXT_CEP_CLI = txtCEP.Text;
    /*e os demais campos*/

    //Se a tela for de edição, altera o valor do ID para o cliente correspondente.
    cliente.ID_CLIENTE_CLI = this.IdCliente;

    ClienteBusiness.SalvarAlteracoes(cliente);

    HTMLHelper.jsAlertAndRedirect(this, "Salvo com sucesso!", ResolveUrl("~/Pages/ClientePage.aspx"));
}

保存更改的方法如下所述:

public static Int32 SalvarAlteracoes(TB_CLIENTE_CLI cliente)
{
    using (PlanoTesteDataContext context = DataContext.ObterConexao())
    {

        if (cliente.ID_CLIENTE_CLI == 0)
        {
            context.TB_CLIENTE_CLIs.InsertOnSubmit(cliente);
        }
        else
        {
            context.TB_CLIENTE_CLIs.Attach(cliente, true);
        }

        context.SubmitChanges();
    } return cliente.ID_CLIENTE_CLI;
}

context.TB_CLIENTE_CLIs.Attach(cliente, true);行上,我收到了System.InvalidOperationException: An entity can only be attached as modified without original state if it declares a version member or does not have an update check policy

我已经检查过UpdateChecks并将它们设置为Never。

我该怎么办?谢谢,抱歉这个糟糕的英语。

2 个答案:

答案 0 :(得分:1)

这应该有效:

else
    {
     context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, cliente);
     context.TB_CLIENTE_CLIs.Attach(cliente);
   }

此Refresh重载将保留用户所做的更改,它将修改后的实体与数据库中的原始值进行比较,检测差异并将实体标记为已修改,并且对SubmitChanges的调用将更新应用于数据库。 / p>

答案 1 :(得分:0)

使用带有断开连接的实体的Linq2SQL可能会遇到麻烦。 EF是一种更适合解决此问题的解决方案。

但是,请确保您已将UpdateCheck上的实体的所有属性设置为NEVER。我自己测试了这个并且它有效。如果这确实有效,它将在每个列上运行UPDATE语句,无论它是否已更新。如果在表上使用触发器,可能会导致问题。最好使用Timestamp来跟踪实体,以便提高多个用户之间的并发问题。

如果您尝试从Attach未设置为ObjectTrackingEnabled的上下文中False实体,那么您将抛出以下异常:

An unhandled exception of type 'System.NotSupportedException' occurred in System.Data.Linq.dll

Additional information: An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext.  This is not supported.

作为示例,请使用以下内容检索并重新附加实体:

    public TB_CLIENTE_CLI Get(int id)
    {
        using (PlanoTesteDataContext ctx = new PlanoTesteDataContext())
        {
            ctx.ObjectTrackingEnabled = false;
            return ctx.TB_CLIENTE_CLI.SingleOrDefault(n => n.ID == id);
        }
    }

    public void Save(TB_CLIENTE_CLI cliente)
    {
        using (PlanoTesteDataContext ctx = new PlanoTesteDataContext())
        {
            ctx.DeferredLoadingEnabled = false;
            ctx.TB_CLIENTE_CLI.Attach(cliente, true);
            ctx.SubmitChanges();
        }
    }

您还需要在DeferredLoadingEnabled方法中将False加载到Save,以便您可以在第一次初始修改后保存对实体的更改。< / p>