I have the following class that I would like to use as property of a Login
object. I'd prefer that this class not have any navigation properties (as it will just be used for quick checks) if that is at all possible, but I'm willing to allow the one shown below.
public class LoginFeature
{
[Key, Column(Order = 0)]
public int RoleId { get; set; } //Role is another table in the db, but not looking for a nav. property or constraint here.
[Key, Column(Order = 1)]
public virtual Login Login { get; set; }
public bool Deny { get; set; }
}
The class containing a collection of these is (stripped down for space)
public class Login
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; } //Database ID
public virtual List<LoginFeature> LoginFeatures { get; set; }
}
My DbContext is defined as
public class MyContext : DbContext
{
public DbSet<Login> Logins { get; set; }
public DbSet<LoginFeature> LoginFeatures { get; set; }
}
But the following test generates an error saying that
System.Data.Entity.Infrastructure.DbUpdateException : An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details. ----> System.Data.UpdateException : An error occurred while updating the entries. See the inner exception for details. ----> System.Data.SqlClient.SqlException : Cannot insert the value NULL into column 'RoleId', table 'TEST.dbo.LoginFeatures'; column does not allow nulls. INSERT fails. The statement has been terminated.
[Test]
public void LoginCanHaveFeatures()
{
using (var ctx = new MyContext())
{
var login = ctx.Logins.FirstOrDefault(x => x.Id == 30);
Assert.IsNotNull(login);
for (int i = 10; i < 15; i++)
{
var feature = new LoginFeature();
feature.Login = login;
feature.RoleId = i;
feature.Deny = true;
login.LoginFeatures.Add(feature);
}
ctx.SaveChanges();
}
}
The SQL being generated as show in EFProf is
insert [dbo].[LoginFeatures]
([Deny],
[Login_Id])
values (1 /* @0 */,
30 /* @1 */)
Which seems to imply that the data annotation attributes on LoginFeature
are incorrect. Is what I am trying to do possible?
Thanks,
Joe