问题
So I have one document table and a ApplicationUser table. One user can upload multiple documents and a foreign key constraint has been applied accordingly using the code first approach. But the problem is, I am able to save the document without assigning the UserID foreign key id in the Documents table. What am I missing here? Below is my novice attempt.
ApplicationUser Model:
it's the standard model provided by the framework.
Document Model:
public class Document
{
public int Id { get; set; }
[StringLength(255)]
public string FileName { get; set; }
[StringLength(100)]
public string ContentType { get; set; }
public byte[] Content { get; set; }
[StringLength(255)]
public string DocumentName { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationUser User { get; set; }
}
Post Action
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Document doc, HttpPostedFileBase uploadedresume)
{
try
{
if (ModelState.IsValid)
{
if (uploadedresume != null && uploadedresume.ContentLength > 0)
{
var tempdoc = new Document
{
FileName = System.IO.Path.GetFileName(uploadedresume.FileName),
ContentType = uploadedresume.ContentType,
DocumentName = doc.DocumentName
};
using (var reader = new System.IO.BinaryReader(uploadedresume.InputStream))
{
tempdoc.Content = reader.ReadBytes(uploadedresume.ContentLength);
}
_context.Documents.Add(tempdoc);
}
// YOU CAN CLEARLY SEE I HAVE NOT SET THE tempdoc.UserId PROPERTY WITH THE LOGGED IN USER ID
// WHY AM I NOT GETTING ERROR HERE CONSTRAINT ERROR??
_context.SaveChanges();
return RedirectToAction("Create");
}
}
catch (RetryLimitExceededException /* dex */){
ModelState.AddModelError("", "");
}
return View("Create");
}
One to Many Migration
public override void Up()
{
CreateTable(
"dbo.Documents",
c => new
{
Id = c.Int(nullable: false, identity: true),
FileName = c.String(maxLength: 255),
ContentType = c.String(maxLength: 100),
Content = c.Binary(),
DocumentName = c.String(maxLength: 255),
UserId = c.String(maxLength: 128),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.AspNetUsers", t => t.UserId)
.Index(t => t.UserId);
}
public override void Down()
{
DropForeignKey("dbo.Documents", "UserId", "dbo.AspNetUsers");
DropIndex("dbo.Documents", new[] { "UserId" });
DropTable("dbo.Documents");
}
}
Entry in Documents table:
Expected Behavior
If I have set up FK constraint properly then I should have seen the constraint error when saving in database. It should not have allowed NULL values because it is not a valid userId that is there in ApplicationUserId Table.
Or nullable foreign key is the expected behavior??
回答1:
Maybe you can configure this in the function onModelCreating into your context file, something like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ApplicationUser>()
.HasMany(u => u.Documents)
.WithRequired(d => d.UserId)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
You will have to create a property in your ApplicationUser class to reference the documents like this:
public ICollection<Document> Documents { get; set; }
回答2:
This happens because you have a relation but this is optional, may be one or none, you have to put this field as a required if you need to make this relation mandatory:
[Required]
public string UserId { get; set; }
来源:https://stackoverflow.com/questions/45571025/how-to-correctly-set-foreign-key-constraint-in-one-to-many-relationship-in-code