使用事务是否会消除使用辅助dataContexts来尝试sql insert / update / deletes的需要?

时间:2009-09-10 15:03:55

标签: linq-to-sql transactions ticket-system

所以我有一个通过Linq-To-Sql存储在数据库中的IT /开发人员票据列表。保存尝试仅在用户请求时完成,或者如果他们说保存在关闭时。我担心的是,用户更改了2张或更多票,而没有保存。

由于某种原因,如果数据库拒绝更改为1,则不会向我提供有关哪个项目或哪个字段上哪个字段存在问题的信息,因此我可以将其绑定回给用户指示。现在我无法将好的数据保存在他们编辑的记录中,因为一个更改卡在队列中,现在SubmitChanges不再起作用。

我构建了一个缓冲系统,其中每个票据被包装在另一个类中,以便将更改保存到缓冲区而不是直接保存到linq到sql对象,其中每个票证都更改了:

  • 我可以创建一个新的dataContext实例
  • 尝试保存单个行的更改
  • 然后向每个失败的用户报告。

我猜的代码有很多气味,或者至少是丑陋的。

我的同事刚建议我尝试交易。我宁愿不拆除我为测试交易方法而构建的内容。

  • 交易是否会正确重置项目的所有更改,或者SaveChanges会尝试保存的所有项目?之后我会期望hasChanges为空,而SaveChanges什么都不做。
  • 有没有更好的方法在linq-to-sql中一次提交单个行更改?
  • 我在SaveChanges异常中遗漏了哪些内容真的会帮助我知道哪一行,以及该行中哪个字段出现问题?

也许我不应该允许(因为linq-to-sql或现实世界不需要能够在不决定保存或不保存的情况下对多个单元进行更改)用户离开票证直到他们决定如果他们想要保存更改吗?

1 个答案:

答案 0 :(得分:0)

我已经推出了自己的缓冲课程,这有点乱,但确实可以一次保存一条记录。

这是包含linq实体的业务对象的父类。

public class BufferedLinqChange
{
    LqGpsDataContext _dataContext;

    internal BufferedLinqChange(LqGpsDataContext dataContext)
    {
        _dataContext = dataContext;
    }

    protected void SetBufferedProperty<T>(string key,Action linqAction
        ,bool linqEqualsValue,Action bufferAction)
    {
        if (linqEqualsValue)
        {
            if (Changes.ContainsKey(key))
                Changes.Remove(key);
        }
        else
        Changes.InsertOrUpdate(key, linqAction); bufferAction();
    }

    protected Dictionary<String, Action> Changes = new Dictionary<string, Action>();

    public int ChangeCount { get { return Changes != null ? Changes.Count : 0; } }
    public bool hasChanges { get { return Changes != null ? Changes.Count > 0 : false; } }

    public void SubmitChanges()
    {
        _dataContext.SubmitChanges();
        if (ChangeCount > 0)
        {
            Changes.ForEach((item) => item.Value.Invoke());
            _dataContext.SubmitChanges();
        }
    }
    public void CancelChanges()
    {
        if (Changes != null)
            Changes.Clear();
    }
}

以下是其中一个属性的示例:

#region assetTag


    String _AssetTag;
    public const String STR_assetTag = "assetTag";
    public String assetTag
    {
        get { return (Changes.ContainsKey(STR_assetTag) ? _AssetTag : Asset.assetTag); }
        set
        {
            SetBufferedProperty<String>(STR_assetTag
                , () => Asset.assetTag = value, Asset.assetTag == value, () => _AssetTag = value);
        }
    }
    #endregion