为什么我会获得重复的行插入?

时间:2012-05-17 17:38:39

标签: linq windows-phone-7 sql-server-ce

我有windows phone 7应用程序和数据库映射类。 Poll类看起来像这样:

    [Table]
public class Poll // :BaseModel
{
    //private int _pid;
    //private string _pdesc;
    //private bool _pisopen;
    //private string _pname;
    //private bool _prandom;
    //private string _qlastupdticks;
    //private string _ticks;

    [Column(DbType = "INT NOT NULL IDENTITY(1,1)", IsPrimaryKey = true, IsDbGenerated = true)]
    public int id { get; set; }

    [Column(DbType = "INT")]
    public int pid { get; set; }
    //{
    //    get { return _pid; }
    //    set { SetValue(ref _pid, value, GetPropertyName(MethodBase.GetCurrentMethod())); }
    //}

    [Column]
    public string pdesc { get; set; }
    //{
    //    get { return _pdesc; }
    //    set { SetValue(ref _pdesc, value, GetPropertyName(MethodBase.GetCurrentMethod())); }
    //}

    [Column]
    public bool pisopen { get; set; }
    //{
    //    get { return _pisopen; }
    //    set { SetValue(ref _pisopen, value, GetPropertyName(MethodBase.GetCurrentMethod())); }
    //}

    [Column]
    public string pname { get; set; }
    //{
    //    get { return _pname; }
    //    set { SetValue(ref _pname, value, GetPropertyName(MethodBase.GetCurrentMethod())); }
    //}

    [Column]
    public bool prandom { get; set; }
    //{
    //    get { return _prandom; }
    //    set { SetValue(ref _prandom, value, GetPropertyName(MethodBase.GetCurrentMethod())); }
    //}

    [Column(DbType = "NVARCHAR(255)")]
    public string qlastupdticks { get; set; }
    //{
    //    get { return _qlastupdticks; }
    //    set { SetValue(ref _qlastupdticks, value, GetPropertyName(MethodBase.GetCurrentMethod())); }
    //}

    [Column(DbType = "NVARCHAR(255)")]
    public string ticks { get; set; }
    //{
    //    get { return _ticks; }
    //    set { SetValue(ref _ticks, value, GetPropertyName(MethodBase.GetCurrentMethod())); }
    //}

    public override bool Equals(object obj)
    {
        var item = obj as Poll;
        if (item != null)
        {
            Equals(item);
        }
        return false;
    }

    public bool Equals(Poll other)
    {
        if (ReferenceEquals(null, other)) return false;
        return (other.pid == pid);
    }

    public override string ToString()
    {
        return string.Format("{0}_{1}", GetType().Name, pid);
    }

    public override int GetHashCode()
    {
        return ToString().ToUpper().GetHashCode();
    }
}

保存方法如下:

 public bool RowsSave<T>(IEnumerable<T> entities, out string error)
    {
        error = string.Empty;
        bool res;
        var type = typeof (T);

        using (var ctx = new PpaDataContext(_connectionString))
        {
            try
            {

                var entitesInDb = ctx.GetTable(type).Cast<T>().ToList();

                var entitesForSave = new List<T>();

                foreach (var entity in entities)
                {
                    if (!entitesInDb.Contains(entity))
                    {
                        entitesForSave.Add(entity);
                    }
                    else
                    {
                        var index = entitesInDb.IndexOf(entity);
                        foreach (var prop in PropertiesGet(entity))
                        {
                            prop.SetValue(entitesInDb[index], prop.GetValue(entity, null), null);
                        }
                    }
                }
                if(entitesForSave.Count > 0)
                {
                    ctx.GetTable(type).InsertAllOnSubmit(entitesForSave);
                }
                ctx.SubmitChanges();
                res = true;
            }
            catch (Exception ex)
            {
                error = string.Format("{0}", ex.Message);
                res = false;
            }
        }
        return res;
    }

当我尝试插入时,每个对象插入两次。这段代码有什么不对? RowsSave方法仅调用一次。

2 个答案:

答案 0 :(得分:0)

这有点事后,但我遇到了完全相同的问题。这与重写的相等运算符中的错误有关。在这种特定情况下,出现问题的原因是代码不返回Equals函数的值:

public override bool Equals(object obj)
{
    var item = obj as Poll;
    if (item != null)
    {
        Equals(item);
    }
    return false;
}

该代码将始终返回false。更正后的代码应为:

public override bool Equals(object obj)
{
    var item = obj as Poll;
    if (item != null)
    {
        return Equals(item);
    }
    return false;
}

LINQ-to-SQL在插入后使用对象等于比较。我不确定在什么情况下以及出现这种情况的原因,但如果比较返回false,它会再次运行插入。如果您遇到相同的行为,请检查实体的任何重写的相等方法是否正确。

答案 1 :(得分:-1)

我认为你不需要这一行:

ctx.SubmitChanges();

正在进行插入:

ctx.GetTable(type).InsertAllOnSubmit(entitesForSave);