这段代码是否适用于通用例程?

时间:2010-12-20 01:02:55

标签: c# linq-to-sql

以下是我刚在Linq2Sql上下文中编写的代码:

 public static CampaignEntity GetOrCreate(int pid, SynchDBDataContext db)
    {
        CampaignEntity ce = (from c in db.CampaignEntities
                             where c.pid == pid
                             select c).FirstOrDefault();
        if (ce == null)
        {
            ce = new CampaignEntity();
            ce.pid = pid;
            db.CampaignEntities.InsertOnSubmit(ce);
        }

        return ce;
    }

制作通用例程的方法是: - 实体类型 - 主键列的类型 - 主键的值

1 个答案:

答案 0 :(得分:2)

我之前看到过的是这样的事情:

public static TEntity GetOrCreate<TEntity, TPKey>(TPKey pid, SyncDBCataContext db,  Func<int, TEntity> create){...}

Func将是创建实体的方法,因此您可以在调用此函数时对其进行内联,或者您可以将其解析并硬编码实体的创建方式,就像您在问题中所做的那样。

这是一个通过id获取的方法:

public T GetById<TEntity, TPKey>(TPKey id, DataContext context) where TEntity : class
{
        MetaTable metaTable = context.Mapping.GetTable(typeof(TEntity));
        MetaDataMember primaryKeyMetaDataMember = metaTable.RowType.DataMembers.SingleOrDefault(d => d.IsPrimaryKey);
        return context.GetTable<TEntity>().SingleOrDefault(GetEqualityLambdaExpression<TEntity>(primaryKeyMetaDataMember.Name, id));
}

这是一个方法,它将为get by id方法创建过滤器的表达式:

public Expression<Func<T, bool>> GetEqualityLambdaExpression<T>(string fieldName, object constantValue)
{
    ParameterExpression param = Expression.Parameter(typeof(T), "e");
    Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(
        Expression.Equal(Expression.Property(param, fieldName),
        Expression.Constant(constantValue)),
        new ParameterExpression[] { param });
    return expression;
}

正如您所看到的,有一些反射的用法。如果性能是一个大问题,您可以实现某种缓存以减少未来调用的开销。