首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化仓库的SubmitChanges方法

优化仓库的SubmitChanges方法
EN

Stack Overflow用户
提问于 2012-06-29 13:34:13
回答 2查看 391关注 0票数 0

我有下面的存储库。我在LINQ2SQL生成的类和使用工厂的域对象之间进行了映射。

下面的代码可以工作,但是我看到了两个潜在的问题

1)在update语句之前使用SELECT查询。

2)它需要更新所有列(不仅仅是已更改的列)。这是因为我们不知道域对象中的所有列都发生了什么变化。

如何克服这些缺点?

注意:可以根据特定的列更新执行一些场景(比如触发器)。因此,我不能不必要地更新列。

参考

  1. LINQ to SQL: Updating without Refresh when “UpdateCheck = Never”
  2. ID=113917

代码语言:javascript
复制
namespace RepositoryLayer
{
public interface ILijosBankRepository
{      
    void SubmitChangesForEntity();
}

public class LijosSimpleBankRepository : ILijosBankRepository
{

    private IBankAccountFactory bankFactory = new MySimpleBankAccountFactory();
    public System.Data.Linq.DataContext Context
    {
        get;
        set;
    }


    public virtual void SubmitChangesForEntity(DomainEntitiesForBank.IBankAccount iBankAcc)
    {
        //Does not get help from automated change tracking (due to mapping)

        //Selecting the required entity
        DBML_Project.BankAccount tableEntity = Context.GetTable<DBML_Project.BankAccount>().SingleOrDefault(p => p.BankAccountID == iBankAcc.BankAccountID);

        if (tableEntity != null)
        {
            //Setting all the values to updates (except primary key)
            tableEntity.Status = iBankAcc.AccountStatus;

            //Type Checking
            if (iBankAcc is DomainEntitiesForBank.FixedBankAccount)
            {
                tableEntity.AccountType = "Fixed";
            }

            if (iBankAcc is DomainEntitiesForBank.SavingsBankAccount)
            {
                tableEntity.AccountType = "Savings";
            }

            Context.SubmitChanges();
        }
    }
}

}

namespace DomainEntitiesForBank
{

public interface IBankAccount
{
    int BankAccountID { get; set; }
    double Balance { get; set; }
    string AccountStatus { get; set; }
    void FreezeAccount();

}

public class FixedBankAccount : IBankAccount
{

    public int BankAccountID { get; set; }
    public string AccountStatus { get; set; }
    public double Balance { get; set; }

    public void FreezeAccount()
    {
        AccountStatus = "Frozen";
    }
}


}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-30 11:09:19

如果我理解您的问题,您将被传递给一个需要保存到数据库中的实体,而不知道原始值是什么,或者哪些列实际上已经更改。

如果是这样的话,那么您有四个选择

  1. 您需要返回到数据库,以查看原始值(如代码所做的那样执行select )。这允许您设置所有实体值,Linq2Sql将负责实际更改哪些列。因此,如果您的列没有实际更改,则不会触发update语句。
  2. 您需要避免选择,只需更新列。您已经知道如何做(但对于其他人,请参见this question and answer)。由于您不知道哪些列已经更改,所以您没有选项,只能将它们全部设置。这将产生一个update语句,即使没有实际更改任何列,并且这可以触发任何数据库触发器。除了禁用触发器之外,这里唯一可以做的事情是确保编写触发器来检查旧的和新的列值,以避免任何不必要的更新。
  3. 您需要更改需求/程序,以便既需要旧的实体值,也需要新的实体值,这样就可以确定哪些列已经更改,而无需返回数据库。
  4. 不要在更新时使用LINQ。LINQ代表语言集成的查询,它在查询方面非常出色,但我总是把更新/删除特性看作是额外的奖励,而不是设计它的目的。另外,如果时机/性能非常关键,那么LINQ就不可能与手工构建的SQL匹配。
票数 1
EN

Stack Overflow用户

发布于 2012-06-30 06:24:52

这并不是一个真正的DDD问题;据我所能告诉你的是:

Use linq to generate direct update without select

如果接受的答案是不可能的,但是有一个更高的投票结果,建议您可以将一个对象附加到您的上下文中,以启动数据上下文的更改跟踪。

关于禁用触发器的第二点已经回答了herehere。但正如其他人所言,你真的需要触发器吗?您不应该在代码中控制这些更新吗?

一般来说,我认为您正在考虑过早的优化。您正在使用ORM,并且作为其中的一部分,您信任L2S为您做出数据库管道决策。但是,请记住,在适当的地方,您可以使用存储过程执行特定的SQL。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11262785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档