AddOrUpdate的通用包装器方法失败

时间:2014-10-13 17:34:03

标签: c# entity-framework ef-migrations

我正在尝试为EF Migrations AddOrUpdate方法编写通用的包装器/扩展方法,但是,在设计时我收到以下错误:

enter image description here

这是我的代码:

public static void InsertOrUpdate(this Object item, Func<Object, Object> PrimaryKeyMember, DbContext Db, Func<DbContext, DbSet> DbSetAttribute, bool Commit = false)
{
    try
    {
        DbSetAttribute.Invoke(Db).AddOrUpdate(PrimaryKeyMember, item);

        //Commit if required
        if (Commit)
            Db.SaveChanges();

    }
    catch (Exception e)
    {
        Trace.TraceError(e.ToString());
        throw;
    }

}

我还不熟悉泛型,但我可以推断出它与AddOrUpdate方法需要&#34;参考类型&#34;这一事实有关。我也尝试了以下内容:

public static void InsertOrUpdate<T>(this Object item, Func<Object, Object> PrimaryKeyMember, DbContext Db, Func<DbContext, DbSet<T>> DbSetAttribute, bool Commit = false)
{
    try
    {
        DbSetAttribute.Invoke(Db).AddOrUpdate<T>(PrimaryKeyMember, item);

        //Commit if required
        if (Commit)
            Db.SaveChanges();

    }
    catch (Exception e)
    {
        Trace.TraceError(e.ToString());
        throw;
    }

}

但是,这会在设计时导致以下错误:

  

类型&#39; T&#39;必须是引用类型才能将其用作参数   泛型类型或方法中的TEntity   blablabla.AddOrUpdate(...)。

我错过了什么?我不确定&#34;参考类型&#34;是...

最终,工作代码

我现在使用以下代码,它使用AddOrUpdate的一个覆盖:

public static void InsertOrUpdate<T>(this T item, Expression<Func<T, object>> IdentifierExpression, DbContext Db, Func<DbContext, IDbSet<T>> DbSetAttribute, bool Commit = false) where T: class
{
    try
    {
        DbSetAttribute.Invoke(Db).AddOrUpdate(IdentifierExpression, item);

        //Commit if required
        if (Commit)
            Db.SaveChanges();

    }
    catch (Exception e)
    {
        Trace.TraceError(e.ToString());
        throw;
    }
}

1 个答案:

答案 0 :(得分:2)

如果您尝试换行此DbSetMigrationsExtensions.AddOrUpdate扩展名,那么我无法理解Func<Object, Object> PrimaryKeyMember的含义。

无论如何,AddOrUpdate被限制为使用类(==引用类型)作为实体类型。因此,您的包装器方法也必须以这种方式进行约束:

public static void InsertOrUpdate<T>(this Object item, Func<Object, Object> PrimaryKeyMember, DbContext Db, Func<DbContext, DbSet<T>> DbSetAttribute, bool Commit = false)
    where T : class
{
     // ...
}

<强> UPD

由于您尝试使用AddOrUpdate的{​​{3}}重载,您应该注意,Func<...>Expression<Func<...>>是两种不同的类型。第一个是委托,第二个是代码的树状表示,可以编译成具有特定签名的委托。

您必须将PrimaryKeyMember参数类型从Func<T, object>更改为Expression<Func<T, object>>