Reputation: 9876
So I am working on this ASP.NET MVC 4
project and I get to this point where I think I can't get my head around the problem. I am using Entity Framework 5
and Code first
workflow. I have those two entities:
public class Document
{
public int DocumentID { get; set; }
public string Name { get; set; }
public string Description
public int UserFileID { get; set; }
public UserFile UserFile { get; set; }
}
and respectively
public class UserFile
{
public int UserFileID { get; set; }
public string FileName { get; set; }
}
Now I have an admin part where I allow the admin to create new Document
and most of the time the user will want to add some kind of file to the document but I want to manage the user uploaded files separately so I have an explicit entity where I plan to store all the uploaded files.
Something that seem very standard but I really can't figure out is this:
I have a form:
@using (Html.BeginForm("Documents", "Admin",
FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.TextBoxFor(m => m.Name)
@Html.TextBoxFor(m => m.Description)
<input name="file" type="file" />
<input type="submit" value="Upload File" id="btnSubmit" />
}
Then in my Controller Action I would like to copy the file and create the records in Document
and UserFile
tables but I just don't see how I'm supposed to do it. I use repositories and UnitOfWork
so in my controller I could first:
UserFile item = new UserFile();
//take the name of the uploaded file and set it for item.Name
unitOfWork.UserFileRepository.Add(item);
But then I have to save the Document
where I can begin again with :
Document entity = new Document();
entity.Name = model.Name;
entity.Description = model.Description;
entity.UserFile = ???
unitOfWork.DocumentRepository.Add(entity);
What I really don't know is how to deal with the foreign key. I have a little experience but as far as I remember in other scenarion I just need to pass object of type UserFile
like:
var entityUserFile = unitOfWork.UserFileRepository.GetById(Id);
and then:
entity.UserFile = entityUserFile;
But I don't see a way to get the ID of the newly created record in UserFile
table. I can think of workaround by setting unique name for each file, but I was wondering is there some way to deal with this. Maybe some Code First
approach where I could create the two entity instances and let the Entity Framework deal with setting the relation, maybe some other way? Or I am obligate to save the UserFile
entity then to get it back and pass it as value for my Document
entity?
Upvotes: 0
Views: 80
Reputation: 22595
Have you tried this?
UserFile item = new UserFile();
Document entity = new Document();
entity.Name = model.Name;
entity.Description = model.Description;
entity.UserFile = item;
unitOfWork.DocumentRepository.Add(entity);
unitOfWork.SaveChanges();
The DbSet.Add()
method marks all objects in the graph as "Added", so the UserFile
should be Added at the same time as Document
.
Reference:
Why does Entity Framework Reinsert Existing Objects into My Database?
Alternatively, EF should fix up your ID when you SaveChanges(). So this should work too :
UserFile item = new UserFile();
unitOfWork.UserFileRepository.Add(item);
unitOfWork.SaveChanges();//Database generates key
//and EF fixes its in-memory version
Document entity = new Document();
entity.Name = model.Name;
entity.Description = model.Description;
entity.UserFileID = item.ID; //use the foreign key to avoid duplicate
unitOfWork.DocumentRepository.Add(entity);
unitOfWork.SaveChanges();
You may wish to enclose this in TransactionScope
because there are now 2 calls to SaveChanges()
Upvotes: 1