1

I am writing mock of DbSets and ended up writing series of code like this.

int rowCount = 0;
var maxOrderId = EntityContainer.Set<Order>().Max(a => a.Id);
var newOrders = EntityContainer.Set<Order>().Where(a =>a.Id == 0);
foreach (var order in newOrders)
{
    order.Id = ++maxOrderId;
    rowCount++;
}

var maxServiceId = EntityContainer.Set<Service>().Max(a => a.Id);
var newServices = EntityContainer.Set<Service>().Where(a => a.Id == 0);
foreach (var service in newServices)
{
    service.Id = ++maxServiceId;
    rowCount++;
}

There are more entities though in this list. Is there a way I can extract these to a generic method? Something like:

int GenerateID<Order>();

I tried using dynamic, but that compiler complains that dynamics are not allowed in lambda expressions.

g t
  • 7,287
  • 7
  • 50
  • 85
Raghav
  • 2,890
  • 7
  • 36
  • 56
  • Maybe not relevant to you case, but have you checked https://github.com/tamasflamich/effort before rolling out your own implementation? – Kaspars Ozols Mar 27 '17 at 06:39

2 Answers2

1

You would have to ensure your objects implement an interface like:

interface IItem
{
    int Id { get; set; }
}

The GenerateId method would then look like this:

int GenerateID<T>(int rowCount) where T : IItem
{
    var maxId = EntityContainer.Set<T>().Max(a => a.Id);
    var newItems = EntityContainer.Set<T>().Where(a => a.Id == 0);
    foreach (T item in newItems)
    {
        item.Id = ++maxId;
        rowCount++;
    }

    return rowCount;
}

Edit

To avoid having to add interfaces, you could pass accessor function/actions:

int GenerateId<T>(int rowCount, Func<T, int> getIdFunc, Action<T, int> setIdFunc)
    where T : class 
{
    var maxId = EntityContainer.Set<T>().Max(getIdFunc);
    var newItems = EntityContainer.Set<T>().Where(a => getIdFunc.Invoke(a) == 0);
    foreach (T item in newItems)
    {
        setIdFunc.Invoke(item, maxId++);
        rowCount++;
    }

    return rowCount;
}

Then call as:

rowCount = GenerateId<Order>(rowCount, o => o.Id, (o, id) => o.Id = id);
rowCount = GenerateId<Service>(rowCount, o => o.Id, (o, id) => o.Id = id);
g t
  • 7,287
  • 7
  • 50
  • 85
0

If I understand right you need autoincrement Id for your model.

Please see this answer

Additionally if you want to set started id just use smth like this

public class Model
{
    private static int m_Counter = 0;
    //
    public static ResetCounter(int start)
    {
        m_Counter=start;
    }
    public int Id { get; set; }

    public Model()
    {
        this.Id = System.Threading.Interlocked.Increment(ref m_Counter);
    }
}

and using

Model.ResetCounter(maxServiceId)//optionally 
new Model {} //now When you create new object Model.Id should increment by itself
Community
  • 1
  • 1
Artsiom Che
  • 122
  • 8