I'm trying to apply a one-to-many for my entities using EF6 and fluent API but keep getting this error:
EmailTemplate_Attachments_Source_EmailTemplate_Attachments_Target: : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical.
These are my models:
public class EmailTemplate
{
public EmailTemplate()
{
Attachments = new List<EmailTemplateAttachment>();
}
public int EmailTemplateId { get; set; }
public int OperatorId { get; set; }
public EmailTemplateType MailType { get; set; }
public int LanguageId { get; set; }
public string Subject { get; set; }
public string Content { get; set; }
public string FromEmail { get; set; }
public DateTime CreationDate { get; set; }
public virtual ICollection<EmailTemplateAttachment> Attachments { get; set; }
}
public class EmailTemplateAttachment
{
public int EmailTemplateAttachmentId { get; set; }
public string ShortDescription { get; set; }
public string FilePath { get; set; }
public int EmailTemplateId { get; set; }
public virtual EmailTemplate EmailTemplate { get; set; }
}
These are the entities configurations
public EmailTemplateConfiguration()
{
ToTable("T_EMAILS");
HasKey(emailTemplate => new { emailTemplate.OperatorId, emailTemplate.MailType, emailTemplate.LanguageId });
HasMany(t => t.Attachments)
.WithRequired(a => a.EmailTemplate)
.HasForeignKey(a => a.EmailTemplateId);
Property(emailTemplate => emailTemplate.EmailTemplateId).HasColumnName("row_id")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(emailTemplate => emailTemplate.OperatorId).HasColumnName("operator_id");
Property(emailTemplate => emailTemplate.MailType).HasColumnName("mail_type");
Property(emailTemplate => emailTemplate.LanguageId).HasColumnName("language_id");
Property(emailTemplate => emailTemplate.Subject).HasColumnName("subject");
Property(emailTemplate => emailTemplate.Content).HasColumnName("mail_content");
Property(emailTemplate => emailTemplate.FromEmail).HasColumnName("from_email");
Property(emailTemplate => emailTemplate.CreationDate).HasColumnName("insert_date");
}
public EmailTemplateAttachmentConfiguration()
{
ToTable("T_EMAILS_ATTACHMENTS");
HasKey(a => a.EmailTemplateAttachmentId);
HasRequired(a => a.EmailTemplate)
.WithMany(t => t.Attachments)
.HasForeignKey(a => a.EmailTemplateId);
Property(a => a.EmailTemplateAttachmentId).HasColumnName("attachment_id")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(a => a.ShortDescription).HasColumnName("short_description");
Property(a => a.FilePath).HasColumnName("file_url");
Property(a => a.EmailTemplateId).HasColumnName("mail_id");
}
What am I doing wrong? I've tried so many wait to configure the foreign key and keep getting the same exception again and again
In your EmailTemplateConfiguration, you define the primary key for EmailTemplate is composite key:
HasKey(emailTemplate => new { emailTemplate.OperatorId, emailTemplate.MailType, emailTemplate.LanguageId });
But in EmailTemplateAttachmentConfiguration, you configure the dependent to use EmailTemplateId as foreign key, which is different from the primary key you defined above. Foreign key should be the same with principal table primary key.
Also, you define the relation between EmailTemplate and EmailTemplateAttachment twice (one in EmailTemplateConfiguration and one in EmailTemplateAttachmentConfiguration). It's redundant, one is enough
Related
I have 2 tables. one for Courses and another one for Keywords.
These two table have many-to-many relations. So I put another table as CourseKeywords.
public class CourseKeyword
{
public int CourseId { get; set; }
public int KeywordId { get; set; }
public virtual Course Course { get; set; }
public virtual Keyword Keyword { get; set; }
}
public class Course
{
[Key]
public int Id { get; set; }
[MaxLength(300)]
public string Title { get; set; }
[MaxLength(300)]
public string SubTitle { get; set; }
public string Body { get; set; }
public ICollection<CourseKeyword> Keywords { get; set; }
public Guid Token { get; set; }
[MaxLength(300)]
public string Photo { get; set; }
[MaxLength(300)]
public string Preview { get; set; }
public bool IsSpecial { get; set; }
}
public class Keyword
{
[Key]
public int Id { get; set; }
[MaxLength(300)]
public string Title { get; set; }
public ICollection<CourseKeyword> CourseKeywords { get; set; }
public ICollection<BlogKeyword> BlogKeywords { get; set; }
}
When I want to add a new course with some new keywords. I successfully add course. Then add keyword, but when I try to add CourseKeyword object, at SaveChange() it shows below error:
InnerException = {"The INSERT statement conflicted with the FOREIGN
KEY constraint "FK_CourseKeywords_Course_KeywordId". The conflict
occurred in database "PandaAcademyNew", table "dbo.Course", column
'Id'.\r\nThe statement has been terminated."}
This happen when I want to save change. My code is here :
var course = _db.Course.Find(model.Id);
var keyw = _db.Keywords.Find(keyword.Id);
var key = new CourseKeyword()
{
Course = course,
Keyword = keyw
};
_db.CourseKeywords.Add(key);
_db.SaveChanges();
This is my context OnModelCreating:
builder.Entity<CourseKeyword>(courseKeyword =>
{
courseKeyword.HasKey(ur => new { ur.KeywordId, ur.CourseId });
courseKeyword.HasOne(ur => ur.Course)
.WithMany(r => r.Keywords)
.HasForeignKey(ur => ur.CourseId)
.IsRequired();
courseKeyword.HasOne(ur => ur.Keyword)
.WithMany(r => r.CourseKeywords)
.HasForeignKey(ur => ur.KeywordId)
.IsRequired();
});
Try this code:
var key = new CourseKeyword()
{
CourseId = course.Id,
KeywordId = keyw.Id
};
_db.CourseKeywords.Add(key);
_db.SaveChanges();
and by the way fix your you dbContext:
builder.Entity<CourseKeyword>(courseKeyword =>
{
courseKeyword.HasKey(ur => new { ur.KeywordId, ur.CourseId });
courseKeyword.HasOne(ur => ur.Course)
.WithMany(r => r.Keywords)
.HasForeignKey(ur => ur.CourseId)
.OnDelete(DeleteBehavior.ClientSetNull);
courseKeyword.HasOne(ur => ur.Keyword)
.WithMany(r => r.CourseKeywords)
.HasForeignKey(ur => ur.KeywordId)
.OnDelete(DeleteBehavior.ClientSetNull);
});
You should try to create new CourseKeyword instance by keys not by entities.
I mean :
var key = new CourseKeyword()
{
CourseId = course.Id,
KeywordId = keyw.Id
};
I have 2 entities connected by a many to many relationship.
First class:
public class ArticleCategory
{
public int Id {get; set; }
public string MainCategoryName { get; set; }
public List<ArticleCategorySubcategory> ArticleCategorySubcategories { get; set; } = new List<ArticleCategorySubcategory>();
public bool IsActive { get; set; }
}
Second class:
public class ArticleSubcategory
{
public int Id { get; set; }
public string SubcategoryName { get; set; }
public List<ArticleCategorySubcategory> ArticleCategorySubcategories { get; set; } = new List<ArticleCategorySubcategory>();
}
And relationship (many to many):
public class ArticleCategorySubcategory : BaseHistoryEntity
{
public int Id { get; set; }
public int ArticleCategoryId { get; set; }
public ArticleCategory ArticleCategory { get; set; }
public int ArticleSubcategoryId { get; set; }
public ArticleSubcategory ArticleSubcategory {get; set;}
}
And I have also 1 DTO:
public class ArticleCategoryResult
{
public string CategoryName { get; set; }
public List<string> Subcategories { get; set; }
public bool IsActive { get; set; }
}
I want to use AutoMapper to list the names of subcategories. I tried something like this but I get an empty list.
My Automapper code:
CreateMap<ArticleCategory, ArticleCategoryResult>()
.ForMember(dst => dst.CategoryName, opt => opt.MapFrom(src => src.MainCategoryName))
.ForMember(dst => dst.IsActive, opt => opt.MapFrom(src => src.IsActive))
.ForMember(dst => dst.Subcategories, src => src.MapFrom(mbr => mbr.ArticleCategorySubcategories.Select(x => x.ArticleSubcategory.SubcategoryName)));
Result on view as json:
{
"categoryName": "Example category 6",
"subcategories": [],
"isActive": true
}
This is what my configuration looks like for these tables:
public void Configure(EntityTypeBuilder<ArticleCategorySubcategory> builder)
{
builder
.HasKey(x => x.Id);
builder
.HasOne(x => x.ArticleCategory)
.WithMany(x => x.ArticleCategorySubcategories)
.HasForeignKey(x => x.ArticleCategoryId);
builder
.HasOne(x => x.ArticleSubcategory)
.WithMany(x => x.ArticleCategorySubcategories)
.HasForeignKey(x => x.ArticleSubcategoryId);
}
How can I list the names of subcategories using AutoMapper?
You need to add .Include(x=>x.ArticleSubcategory) before your .Select(.. as the related objects are not tracked and are treated as undefined.
I'm trying to achieve the following layout:
User table (has link to user details)
User details table (holds links to various detail tables)
but am getting the following error:
System.InvalidOperationException: Cannot create a relationship between 'Address.ClientDetails' and 'ClientDetails.ResidentialAddress', because there already is a relationship between 'ClientDetails.PostalAddress' and 'Address.ClientDetails'. Navigation properties can only participate in a single relationship.
I understand this problem would occur if entity framework had no way to identify which address to link to each address - but i thought i take care of that by specifying 2 links in the model and then each key map in the mapping class. Any help would be great!
my Client model and mapping looks as follows:
public class Client : BaseEntity
{
public ClientDetails ApplicantDetails
{
get
{
return this.ClientDetails.SingleOrDefault(e => e.ClientType == Enums.ClientType.Applicant.ToString());
}
}
public ClientDetails SpouseDetails
{
get
{
return this.ClientDetails.SingleOrDefault(e => e.ClientType == Enums.ClientType.Spouse.ToString());
}
}
public ICollection<ClientDetails> ClientDetails { get; set; }
public ICollection<BankDetails> BankDetails { get; set; }
public ICollection<Expenses> Expenses { get; set; }
public ICollection<Obligation> Obligations { get; set; }
public ICollection<Budget> Budgets { get; set; }
public ICollection<Document.Document> Documents { get; set; }
public virtual Workflow.Workflow Workflow { get; set; }
Mapping
public class ClientMapping: IEntityTypeConfiguration<Entities.Client.Client>
{
public void Configure(EntityTypeBuilder<Entities.Client.Client> builder)
{
builder.ToTable("Client");
builder.HasKey(e => e.Id);
builder.HasMany(e => e.ClientDetails).WithOne(e => e.Client).HasForeignKey(e => e.ClientId);
builder.HasMany(e => e.Documents).WithOne(e => e.Client).HasForeignKey(e => e.ClientId);
builder.HasOne(e => e.Workflow).WithOne(e => e.Client).HasForeignKey<Entities.Workflow.Workflow>(e => e.ClientId);
builder.HasMany(e => e.Obligations).WithOne(e => e.Client).HasForeignKey(e => e.ClientId);
builder.HasMany(e => e.Expenses).WithOne(e => e.Client).HasForeignKey(e => e.ClientId);
builder.HasMany(e => e.Budgets).WithOne(e => e.Client).HasForeignKey(e => e.ClientId);
builder.HasMany(e => e.BankDetails).WithOne(e => e.Client).HasForeignKey(e => e.ClientId);
builder.Ignore(e => e.ApplicantDetails);
builder.Ignore(e => e.SpouseDetails);
}
}
Client Details and mapping
public class ClientDetails
{
public int ClientId { get; set; }
public int PersonalDetailsId { get; set; }
public int EmployerId { get; set; }
public int ResidentialAddressId { get; set; }
public int PostalAddressId { get; set; }
public int IncomeId { get; set; }
public string ClientType { get; set; }
public virtual Client Client { get; set; }
public virtual PersonalDetails PersonalDetails { get; set; }
public virtual Employer Employer { get; set; }
public virtual Address ResidentialAddress { get; set; }
public virtual Address PostalAddress { get; set; }
public virtual Income Income { get; set; }
}
mapping
public class ClientDetailsMapping : IEntityTypeConfiguration<Entities.Client.ClientDetails>
{
public void Configure(EntityTypeBuilder<ClientDetails> builder)
{
builder.ToTable("ClientDetails");
builder.HasKey(e => new { e.IncomeId, e.PersonalDetailsId, e.ClientId, e.PostalAddressId, e.ResidentialAddressId } );
builder.HasOne(e => e.Income).WithOne(e => e.ClientDetails).HasForeignKey<ClientDetails>(e => e.IncomeId);
builder.HasOne(e => e.PostalAddress).WithOne(e => e.ClientDetails).HasForeignKey<ClientDetails>(e => e.PostalAddressId);
builder.HasOne(e => e.ResidentialAddress).WithOne(e => e.ClientDetails).HasForeignKey<ClientDetails>(e => e.ResidentialAddressId);
builder.HasOne(e => e.Employer).WithOne(e => e.ClientDetails).HasForeignKey<ClientDetails>(e => e.EmployerId);
builder.HasOne(e => e.PersonalDetails).WithOne(e => e.ClientDetails).HasForeignKey<ClientDetails>(e => e.PersonalDetailsId);
}
}
Can you try to delete the content of "WithOne"?
try this:
builder.HasOne(e => e.PostalAddress).WithOne().HasForeignKey<ClientDetails>(e => e.PostalAddressId);
builder.HasOne(e => e.ResidentialAddress).WithOne().HasForeignKey<ClientDetails>(e => e.ResidentialAddressId);
Found this post:
ef core - two one to one on one principal key
Ended up implementing solution 3, client details now has a collection of addresses (which have an address type linked), I then added an address getter on the client details to get the address I want at a later time. Everything seems to work correctly now.
I am having a problem with Fluent and Entity Framework.
To start, I created a new database project and used Reverse Engineer Code First to generate a set of Models and Maps.
If I look at the tables in the existing database, I have a table called Parcel and a table called ParcelAgremment.
When I look at the mappings for the two tables I see:
public class ParcelMap : EntityTypeConfiguration<Parcel>
{
public ParcelMap()
{
// Primary Key
this.HasKey(t => t.ParcelId);
// Properties
this.Property(t => t.ParcelReference)
.IsRequired()
.HasMaxLength(20);
this.Property(t => t.ParcelDescription)
.HasMaxLength(1000);
// Table & Column Mappings
this.ToTable("Parcel");
this.Property(t => t.ParcelId).HasColumnName("ParcelId");
this.Property(t => t.SiteId).HasColumnName("SiteId");
this.Property(t => t.ParentParcelId).HasColumnName("ParentParcelId");
this.Property(t => t.IsCurrent).HasColumnName("IsCurrent");
this.Property(t => t.ParcelTypeId).HasColumnName("ParcelTypeId");
this.Property(t => t.ParcelReference).HasColumnName("ParcelReference");
this.Property(t => t.ParcelDescription).HasColumnName("ParcelDescription");
// Relationships
this.HasOptional(t => t.Parcel2)
.WithMany(t => t.Parcel1)
.HasForeignKey(d => d.ParentParcelId);
this.HasRequired(t => t.ParcelType)
.WithMany(t => t.Parcels)
.HasForeignKey(d => d.ParcelTypeId);
this.HasRequired(t => t.Site)
.WithMany(t => t.Parcels)
.HasForeignKey(d => d.SiteId);
}
}
public class ParcelAgreementMap : EntityTypeConfiguration<ParcelAgreement>
{
public ParcelAgreementMap()
{
// Primary Key
this.HasKey(t => t.ParcelAgreementId);
// Properties
// Table & Column Mappings
this.ToTable("ParcelAgreement");
this.Property(t => t.ParcelAgreementId).HasColumnName("ParcelAgreementId");
this.Property(t => t.ParcelId).HasColumnName("ParcelId");
this.Property(t => t.AgreementTypeId).HasColumnName("AgreementTypeId");
this.Property(t => t.RightsChecked).HasColumnName("RightsChecked");
this.Property(t => t.OptionRightsTypeId).HasColumnName("OptionRightsTypeId");
this.Property(t => t.AgreementDate).HasColumnName("AgreementDate");
this.Property(t => t.AgreementNotes).HasColumnName("AgreementNotes");
this.Property(t => t.ConditionsChecked).HasColumnName("ConditionsChecked");
this.Property(t => t.IsAssignable).HasColumnName("IsAssignable");
// Relationships
this.HasOptional(t => t.OptionRightsType).WithMany(t => t.ParcelAgreements).HasForeignKey(d => d.OptionRightsTypeId);
this.HasRequired(t => t.AgreementType).WithMany(t => t.ParcelAgreements).HasForeignKey(d => d.AgreementTypeId);
this.HasRequired(t => t.Parcel).WithMany(t => t.ParcelAgreements).HasForeignKey(d => d.ParcelId);
}
}
and the model files are:
public class Parcel : Entity
{
public Parcel()
{
this.LandTransactionElements = new List<LandTransactionElement>();
this.Parcel1 = new List<Parcel>();
this.ParcelAgreements = new List<ParcelAgreement>();
this.ParcelDeedPackets = new List<ParcelDeedPacket>();
this.ParcelExceptions = new List<ParcelException>();
this.ParcelFinancialTemplates = new List<ParcelFinancialTemplate>();
this.ParcelNote = new List<ParcelNote>();
this.ParcelOptions = new List<ParcelOption>();
this.ParcelReferences = new List<ParcelReference>();
this.ParcelRentPayments = new List<ParcelRentPayment>();
this.ParcelRights = new List<ParcelRight>();
this.ParcelStampDuties = new List<ParcelStampDuty>();
this.ParcelVolumes = new List<ParcelVolume>();
this.ReviewPlans = new List<ReviewPlan>();
}
public int ParcelId { get; set; }
public int SiteId { get; set; }
public Nullable<int> ParentParcelId { get; set; }
public bool IsCurrent { get; set; }
public int ParcelTypeId { get; set; }
public string ParcelReference { get; set; }
public string ParcelDescription { get; set; }
public virtual ICollection<LandTransactionElement> LandTransactionElements { get; set; }
public virtual ICollection<Parcel> Parcel1 { get; set; }
public virtual Parcel Parcel2 { get; set; }
public virtual ParcelType ParcelType { get; set; }
public virtual Site Site { get; set; }
public virtual ICollection<ParcelAgreement> ParcelAgreements { get; set; }
public virtual ICollection<ParcelDeedPacket> ParcelDeedPackets { get; set; }
public virtual ICollection<ParcelException> ParcelExceptions { get; set; }
public virtual ICollection<ParcelFinancialTemplate> ParcelFinancialTemplates { get; set; }
public virtual ICollection<ParcelNote> ParcelNote { get; set; }
public virtual ICollection<ParcelOption> ParcelOptions { get; set; }
public virtual ICollection<ParcelReference> ParcelReferences { get; set; }
public virtual ICollection<ParcelRentPayment> ParcelRentPayments { get; set; }
public virtual ICollection<ParcelRight> ParcelRights { get; set; }
public virtual ICollection<ParcelStampDuty> ParcelStampDuties { get; set; }
public virtual ICollection<ParcelVolume> ParcelVolumes { get; set; }
public virtual ICollection<ReviewPlan> ReviewPlans { get; set; }
}
}
public class ParcelAgreement : Entity
{
public int ParcelAgreementId { get; set; }
public int ParcelId { get; set; }
public int AgreementTypeId { get; set; }
public bool RightsChecked { get; set; }
public Nullable<int> OptionRightsTypeId { get; set; }
public Nullable<System.DateTime> AgreementDate { get; set; }
public string AgreementNotes { get; set; }
public Nullable<bool> ConditionsChecked { get; set; }
public Nullable<bool> IsAssignable { get; set; }
public virtual AgreementType AgreementType { get; set; }
public virtual OptionRightsType OptionRightsType { get; set; }
public virtual Parcel Parcel { get; set; }
}
I am calling the database using
var retData = parcelRepository
.Query(s=> s.ParcelId == optionId)
.Select()
.ToList();
The query works, but when I try to access the ParcelAgreement object from the Parecl object I get following error
InnerException {"Invalid object name 'dbo.ParcelAgreements'."} System.Exception {System.Data.SqlClient.SqlException}
The table is called ParcelAgreement not ParcelAgreements in the database.
If check the project by using a global search for ParcelAgreements, it returns nothing found.
I have other tables that are linked which also does not have a plural table name and it is recovering the data fine.
As per request: Update
In my context file.
public DbSet<Parcel> Parcels { get; set; }
public DbSet<ParcelAgreement> ParcelAgreements { get; set; }
And in the OnModelCreating sub.
modelBuilder.Configurations.Add(new ParcelMap());
modelBuilder.Configurations.Add(new ParcelAgreementMap());
Update 11th May
After looking around it appears that the fix is to add
modelBuilder.Conventions.Remove<PluralizingEntitySetNameConvention>();
to OnModelCreating. As per Link to SO article
unfortunatley this also does not work.
My code looks like
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Configurations.Add(new ActivityMap());
...
... <List of other table>
}
On running I still get the error:
{"Invalid object name 'dbo.ActivityMaps'."} System.Exception {System.Data.SqlClient.SqlException}
As you can see it is still trying to pluralize the table name.
I am using EF 6.0.0.0
This is how I solved it: modelBuilder.Conventions.Remove<PluralizingEntitySetNameConvention>();
Hi i am using CTP5 to map between two entities like that:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public bool IsManager { get; set; }
public decimal Credit { get; set; }
public int CreditAlertCount { get; set; }
public decimal TelPrice { get; set; }
public decimal CellPrice { get; set; }
public DateTime InsertDate { get; set; }
public IList<string> PhoneList { get; set; }
public int UserTypeId { get; set; }
public virtual UserType UserType { get; set; }
}
public class UserType
{
public int Id { get; set; }
public int UserLevel { get; set; }
public string TypeDescription { get; set; }
}
//here is configurations
public class UserConfig : EntityTypeConfiguration<User>
{
public UserConfig()
{
HasKey(c => c.Id);
Property(c => c.Id).HasDatabaseGenerationOption(DatabaseGenerationOption.Identity).HasColumnName("ID");
Property(c => c.InsertDate).HasDatabaseGenerationOption(DatabaseGenerationOption.Computed).HasColumnName("INSERT_DATE");
Property(c => c.IsManager).HasDatabaseGenerationOption(DatabaseGenerationOption.Computed).HasColumnName("IS_MANAGER");
Property(c => c.UserName).HasMaxLength(25).IsRequired().HasColumnName("USER_NAME");
Property(c => c.Password).HasMaxLength(25).IsRequired().HasColumnName("USER_PASSWORD");
Property(c => c.CellPrice).IsRequired().HasColumnName("CELL_PRICE");
Property(c => c.TelPrice).IsRequired().HasColumnName("TEL_PRICE");
Property(c => c.CreditAlertCount).IsRequired().HasColumnName("CREDIT_ALERT_COUNT");
Property(c => c.Credit).IsRequired().HasColumnName("CREDIT");
Property(c => c.UserTypeId).IsOptional().HasColumnName("USER_TYPE_ID");
/*relationship*/
HasRequired(p => p.UserType).WithMany().IsIndependent().Map(m => m.MapKey(p => p.Id, "USER_TYPE_ID"));
ToTable("CRMC_USERS", "GMATEST");
}
}
public class UserTypeConfig : EntityTypeConfiguration<UserType>
{
public UserTypeConfig()
{
/*Identity*/
HasKey(c => c.Id);
Property(c => c.Id).HasDatabaseGenerationOption(DatabaseGenerationOption.Identity).HasColumnName("ID");
/*simple scalars*/
Property(s => s.TypeDescription).IsRequired().HasColumnName("DESCRITPION");
Property(s => s.UserLevel).IsRequired().HasColumnName("USER_LEVEL");
ToTable("CRMC_USER_TYPES", "GMATEST");
}
}
What do i do wrong my User.UserType = null?
How to hell do i map this to work!?
I am dying here for 3 days to work it off.
I'm using DevArt Connection 6.058... some thing
Oracle 10g, C# EntityFramework 4.0
You've setup a required association between User and UserType, therefore you cannot have a User object without a UserType (i.e. User.UserType == null). To be able to do that you need to make 2 changes to your object model and fluent API:
1.Change the type of UserTypeId property to int?:
public int? UserTypeId { get; set; }
2.Remove the code from your fluent API that reads:
HasRequired(p => p.UserType).WithMany().IsIndependent().Map(m => m.MapKey...
You don't need any of those stuff. Everything will be configured by Code First based on convention for you.