patterncsharpMinor
Exporting site and address data
Viewed 0 times
addressexportingsiteanddata
Problem
These two methods do very similar things. Is it possible to condense these somehow? This is using the Entity Framework.
public void ExportSiteData (FLEX_INV_EXP_SITE siteData)
{
var uniqueSite = from e in _context.FLEX_INV_EXP_SITE
where e.SITE_ID == siteData.SITE_ID
select e;
var count = uniqueSite.Count();
if (count != 0) return;
_context.FLEX_INV_EXP_SITE.AddObject(siteData);
_context.SaveChanges();
}
public void ExportAddressData (FLEX_INV_EXP_ADDRESS addressData)
{
var uniqueSite = from e in _context.FLEX_INV_EXP_ADDRESS
where e.SITE_ID == addressData.SITE_ID
select e;
var count = uniqueSite.Count();
if (count != 0) return;
_context.FLEX_INV_EXP_ADDRESS.AddObject(addressData);
_context.SaveChanges();
}Solution
It seems the only two unique things about the blocks of code are the Tables that you are searching/adding to and how the
Then to use it, you could do something like this:
SITE_IDs are obtained (from different types). You could just make your method accept two additional parameters, the table that is being searched and a lambda which selects the SITE_ID. You'll just have to rewrite some expressions.public static void ExportData(
ObjectSet table,
Expression> siteIdSelector,
TEntity data)
where TEntity : class
{
var condition = GetCondition(siteIdSelector, data);
var isInTable = table.Where(condition).Any();
if (!isInTable)
{
table.AddObject(data);
table.Context.SaveChanges();
}
}
private static Expression> GetCondition(
Expression> keySelector,
TEntity data)
where TEntity : class
{
var entity = Expression.Parameter(typeof(TEntity), "entity");
var entityKey = BindParameter(keySelector, entity);
var dataKey = BindParameter(keySelector, Expression.Constant(data));
var body = Expression.Equal(entityKey , dataKey);
return Expression.Lambda>(body, entity);
}
private static Expression BindParameter(
Expression> keySelector,
Expression entity)
where TEntity : class
{
return new SubstitutionVisitor
{
OldExpr = keySelector.Parameters.Single(),
NewExpr = entity,
}.Visit(keySelector.Body);
}
public class SubstitutionVisitor : ExpressionVisitor
{
public Expression OldExpr { get; set; }
public Expression NewExpr { get; set; }
public override Expression Visit(Expression node)
{
return (node == OldExpr) ? NewExpr : base.Visit(node);
}
}Then to use it, you could do something like this:
ExportData(_context.FLEX_INV_EXP_SITE, entity => entity.SITE_ID, siteData);
ExportData(_context.FLEX_INV_EXP_ADDRESS, entity => entity.SITE_ID, addressData);Code Snippets
public static void ExportData<TEntity, TSite>(
ObjectSet<TEntity> table,
Expression<Func<TEntity, TSite>> siteIdSelector,
TEntity data)
where TEntity : class
{
var condition = GetCondition(siteIdSelector, data);
var isInTable = table.Where(condition).Any();
if (!isInTable)
{
table.AddObject(data);
table.Context.SaveChanges();
}
}
private static Expression<Func<TEntity, bool>> GetCondition<TEntity, TKey>(
Expression<Func<TEntity, TKey>> keySelector,
TEntity data)
where TEntity : class
{
var entity = Expression.Parameter(typeof(TEntity), "entity");
var entityKey = BindParameter(keySelector, entity);
var dataKey = BindParameter(keySelector, Expression.Constant(data));
var body = Expression.Equal(entityKey , dataKey);
return Expression.Lambda<Func<TEntity, bool>>(body, entity);
}
private static Expression BindParameter<TEntity, TKey>(
Expression<Func<TEntity, TKey>> keySelector,
Expression entity)
where TEntity : class
{
return new SubstitutionVisitor
{
OldExpr = keySelector.Parameters.Single(),
NewExpr = entity,
}.Visit(keySelector.Body);
}
public class SubstitutionVisitor : ExpressionVisitor
{
public Expression OldExpr { get; set; }
public Expression NewExpr { get; set; }
public override Expression Visit(Expression node)
{
return (node == OldExpr) ? NewExpr : base.Visit(node);
}
}ExportData(_context.FLEX_INV_EXP_SITE, entity => entity.SITE_ID, siteData);
ExportData(_context.FLEX_INV_EXP_ADDRESS, entity => entity.SITE_ID, addressData);Context
StackExchange Code Review Q#7488, answer score: 2
Revisions (0)
No revisions yet.