1

I need to write objects to a table, knowing that I will only know in which table the object will be written at runtime.

For this I created a Dictionary with key and value defining the name of the field of the table and its value. However when I try to write this object in the bank I get error value cannot be null. r nparameter name entitytype.

Dictionary<string, string> myobject = new Dictionary<string, string>();

myobject.Add("id_Lote", idLote.ToString());
myobject.Add("nr_Recuperacao", lote.nr_Recuperacao.ToString());
myobject.Add("id_Cliente", lote.id_Cliente);
myobject.Add("id_Produto", lote.id_Produto);

foreach (var item in loteDto.ItensCapaLote)
{
    myobject.Add(item.id_ItemCapaLote.Replace(" ",""), item.valor);
}

public void NovoTipoCapaLote(dynamic myobject, string nameTable)
{
    db.Set(nameTable).Add(myobject);
    db.SaveChanges();
}
Peter B
  • 22,460
  • 5
  • 32
  • 69
Eriton Silva
  • 129
  • 1
  • 10

2 Answers2

0

It looks like you are trying to save the object before populating all the required properties.

I suggest setting the value of entityType to a valid value before trying to save the object. Assuming there are no other missing properties, that should resolve your issue.

James S
  • 171
  • 1
  • 6
  • I checked that all table fields are in my Dynamic Object Dictionary. In my object the value of the Id is as string in the database is int, could this be the problem? – Eriton Silva Apr 11 '18 at 14:27
  • I don't think that it will be this that is causing that error message, but if you don't correct it then I would expect you to see another error as soon as you have this one fixed. Entity Framework will only give you one error message at a time, it won't tell you all the things that are wrong in one go, only the first thing that caused it fall over! – James S Apr 11 '18 at 14:49
  • I think problem is that my dictionary is a collection of objects, but it should be a single object with properties, how can I make this conversion? – Eriton Silva Apr 12 '18 at 12:15
  • I see. Perhaps it's worth changing tack in that case. Jordan's suggestion (below) looks sensible and I think you'll have more luck pursuing that line of reasoning. The link they have provided gives you the information you need to convert your dictionary into the correct object, and their answer should provide you solid starting point from there :) – James S Apr 12 '18 at 12:59
0

I'm not sure if you can achieve this using a Dictionary. You can dynamically add objects, but from my experience the actual object type needs to match the entity framework object type. I believe you would first need to deserialize it to that type, something like this: Mapping object to dictionary and vice versa.

The reference type can still just be object so that it can be figured out at run-time, but once you have that you can create a method in your entity framework context class to add to a table based on the object passed in using reflection, something like this. I'm sure this code could be simplified, but I don't work with reflection often, just hoping this gives you some ideas.

    public void Add(Object o)
    {
        var contextProperties = this.GetType().GetProperties();
        contextProperties = contextProperties.Where(s => s.PropertyType.IsGenericType && s.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)).ToArray<PropertyInfo>();
        PropertyInfo DbSetToUpdate = contextProperties.Where(s => s.PropertyType.GetGenericArguments()[0] == o.GetType()).FirstOrDefault();
        object DbSetInstance = DbSetToUpdate.GetValue(this, null);
        Type DbSetType = DbSetInstance.GetType();
        MethodInfo DbSetMethod = DbSetType.GetMethod("Add");
        DbSetMethod.Invoke(DbSetInstance, new object[] { o });
    }
Jordan Ryder
  • 2,336
  • 1
  • 24
  • 29
  • The problem is that I will only know the object type at runtime, and I can not pass this type as a parameter to do the reflection as in the example, because I only have the type name and not the type. – Eriton Silva Apr 12 '18 at 15:04
  • Fair enough. We're doing something very similar in our environment, and we generate the classes dynamically. Look up Activator.CreateInstance. If you know the name of the table which you show in your example, then you can generate the class and then update the properties from your dictionary values via reflection. Then you have an actual object that can be passed to entity framework. I think the only other option would be to generate dynamic SQL. Either way, good luck, sir. – Jordan Ryder Apr 12 '18 at 21:32