I have an entity like this:
public class Survey : EntityBase
{
protected Survey()
{
}
public Survey(long id, int version, string title, long userId, string phone)
{
Id = id;
CreationTimeUtc = DateTimeOffset.UtcNow;
Version = version;
Title = title;
UserId = userId;
Phone = phone;
Status = SurveyStatus.Initial;
IsDeleted = false;
Questions = new List<SurveyQuestion>();
Feedbacks = new List<SurveyFeedback>();
}
public int Version { get; protected set; }
public long UserId { get; protected set; }
public string Phone { get; protected set; }
public string Title { get; protected set; }
public SurveyStatus Status { get; protected set; }
public bool IsDeleted { get; protected set; }
public ICollection<SurveyQuestion> Questions { get; protected set; }
public ICollection<SurveyFeedback> Feedbacks { get; protected set; }
public void AddQuestion(SurveyQuestionAddedEvent @event)
{
var question = new SurveyQuestion(@event.QuestionId, @event.CreationDateTimeUtc, @event.AggregateId, null, @event.Order, @event.Description, @event.MultiSelectOption,
@event.Options.Select((t, i) => new SurveyOption(@event.QuestionId, t.Key, i + 1, t.Value)).ToList()
);
Questions.Add(question);
Version = @event.Version;
ModificationTimeUtc = @event.CreationDateTimeUtc;
}
}
And SurveyQuestion
is this:
public class SurveyQuestion : EntityBase
{
private SurveyQuestion()
{
}
public SurveyQuestion(long questionId, DateTimeOffset creationTimeUtc, long surveyId, long? parentId, byte order, string question, bool multiSelectOption, ICollection<SurveyOption> options)
{
Id = questionId;
CreationTimeUtc = creationTimeUtc;
SurveyId = surveyId;
ParentId = parentId;
Order = order;
Question = question;
MultiSelectOption = multiSelectOption;
Options = options;
}
public long SurveyId { get; protected set; }
public long? ParentId { get; protected set; }
public byte Order { get; protected set; }
public string Question { get; protected set; }
public bool MultiSelectOption { get; protected set; }
public ICollection<SurveyOption> Options { get; protected set; }
}
And I have a repository:
public class SurveyRepository : RepositoryBase<Survey>, ISurveyRepository
{
public SurveyRepository(EntityContext context) : base(context)
{
}
public async Task AddAsync(Survey survey) => await Set.AddAsync(survey);
public async Task<Survey?> FindByIdAsync(long id)
=> await Set.AsNoTracking()
.Include(t => t.Questions)
.ThenInclude(t => t.Options)
.FirstOrDefaultAsync(t => t.Id == id);
public async Task AddQuestionAsync(Survey survey, SurveyQuestionAddedEvent @event)
=> await Task.Factory.StartNew(() => {
survey.AddQuestion(@event);
Set.Update(survey);
});
}
And the RepositoryBase
class is:
public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : EntityBase
{
protected RepositoryBase(DbContext context)
{
Set = context.Set<T>();
}
public DbSet<T> Set { get; private set; }
}
In Service class I find a Survey by id that Question
property is empty (count = 0).
When I add a question in collection of questions in survey questions, tracker set question to modify
instead of Add
.
Why is this happening?
I can change EntityState
manually but I imaging EF Core should solve this problem.
2
I am not sure about which entity you are talking about, but:
for SurveyQuestion
, you create object like this:
public SurveyQuestion(long questionId,DateTimeOffset creationTimeUtc,long surveyId,long? parentId,byte order,string question,bool multiSelectOption,ICollection<SurveyOption> options) {
Id = questionId;
CreationTimeUtc = creationTimeUtc;
SurveyId = surveyId;
ParentId = parentId;
Order = order;
Question = question;
MultiSelectOption = multiSelectOption;
Options = options;
}
so, you populate Id
. For survey
you have already existing entity (with Id
populated already).
So, Update
method, as per docs (emphasis mine):
For entity types with generated keys if an entity has its primary key value set then it will be tracked in the Modified state. If the primary key value is not set then it will be tracked in the Added state.
will mark the entity as Modified