优化 Repository 的 SubmitChanges 方法 [英] Optimizing Repository’s SubmitChanges Method

查看:14
本文介绍了优化 Repository 的 SubmitChanges 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下存储库.我有一个使用工厂的 LINQ 2 SQL 生成类和域对象之间的映射.

I have following repository. I have a mapping between LINQ 2 SQL generated classes and domain objects using a factory.

以下代码将起作用;但我看到了两个潜在的问题

The following code will work; but I am seeing two potential issues

1) 它在更新语句之前使用 SELECT 查询.

1) It is using a SELECT query before update statement.

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

2) It need to update all the columns (not only the changed column). This is because we don’t know what all columns got changed in the domain object.

如何克服这些缺点?

注意:可能存在基于特定列更新执行的场景(如触发器).所以我不能不必要地更新列.

Note: There can be scenarios (like triggers) which gets executed based on specific column update. So I cannot update a column unnecessarily.

参考:

  1. LINQ to SQL:更新时不刷新UpdateCheck = 从不"

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=113917

代码

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";
    }
}


}

推荐答案

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

If I understand your question, you are being passed an entity that you need to save to the database without knowing what the original values were, or which of the columns have actually changed.

如果是这样,那么你有四种选择

If that is the case, then you have four options

  1. 您需要返回数据库查看原始值,即执行选择,正如您的代码所做的那样.这允许您设置所有实体值,Linq2Sql 将负责实际更改哪些列.因此,如果您的任何列都没有实际更改,则不会触发更新语句.

  1. You need to go back to the database to see the original values ie perform the select, as you code is doing. This allows you to set all your entity values and Linq2Sql will take care of which columns are actually changed. So if none of your columns are actually changed, then no update statement is triggered.

您需要避免选择并只更新列.您已经知道该怎么做(但对于其他人,请参阅这个问答).由于您不知道哪些列已更改,因此您别无选择,只能将它们全部设置.即使实际上没有更改任何列,这也会产生更新语句,并且这可以触发任何数据库触发器.除了禁用触发器之外,您在这里唯一可以做的就是确保编写触发器以检查旧列和新列的值,以避免任何进一步的不必要更新.

You need to avoid the select and just update the columns. You already know how to do (but for others see this question and answer). Since you don't know which columns have changed you have no option but set them all. This will produce an update statement even if no columns are actually changed and this can trigger any database triggers. Apart from disabling the triggers, about the only thing you can do here is make sure that the triggers are written to check the old and new columns values to avoid any further unnecessary updates.

您需要更改您的要求/程序,以便同时需要旧的和新的实体值,这样您就可以确定哪些列发生了更改,而无需返回数据库.

You need to change your requirements/program so that you require both old and new entities values, so you can determine which columns have changed without going back to the database.

不要使用 LINQ 进行更新.LINQ 代表 Language Integrated QUERY,它在查询方面非常出色(恕我直言),但我总是将更新/删除功能视为额外的奖励,而不是它的设计目的.此外,如果时间/性能很关键,那么 LINQ 就不可能与手工编写的 SQL 正确匹配.

Don't use LINQ for your updates. LINQ stands for Language Integrated QUERY and it is (IMHO) brilliant at query, but I always looked on the updating/deleting features as an extra bonus, but not something which it was designed for. Also, if timing/performance is critical, then there is no way that LINQ will match properly hand-crafted SQL.

这篇关于优化 Repository 的 SubmitChanges 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆