Your problem is setting entry state to Added - that changes whole object graph to Added state (i.e. including all referenced entities). You can avoid adding new Student
entry if you will use StudentId
property instead of using Student
object in saved entity. Or if you will manually set entity state of student to Unchanged or Modified.
First option is making your Save
method non-generic. That will allow you to set navigation property state directly:
context.Entry(issueMaster.Student).State = EntityState.Unchanged;
But if you want to have generic method, your only option is reflection (which is performance hit). Thus all your entities are inherited from base Entity
type, you can get properties which are inherited from Entity
type and check their id. If it has Guid.Empty
value, then object is new and was not saved in database, otherwise you should set appropriate state of entity:
public static bool SaveOnlyAddedEntities<T>(T entity) where T : Entity
{
var context = new ZorgContext();
context.Entry(entity).State = EntityState.Added;
var entry = context.Entry(entity);
Type type = typeof(T);
var flags = BindingFlags.Instance | BindingFlags.Public;
var unchangedDependencies =
type.GetProperties(flags)
.Where(p => p.PropertyType.IsSubclassOf(typeof(Entity)))
.Select(p => (Entity)p.GetValue(entity))
.Where(e => e.Id != Guid.Empty);
foreach (var dependency in unchangedDependencies)
context.Entry(dependency).State = EntityState.Unchanged;
return context.SaveChanges() > 0;
}
Note: this approach shows working with non-collection properties.