EF6 migration - FK to entity with composite Key error - entity-framework-6

I have the following entities:
public class MeetingAttendee
{
public int MeetingId { get; set; }
public Meeting Meeting { get; set; }
public int UserId { get; set; }
public User User { get; set; }
public IEnumerable<MeetingAttendanceEntry> MeetingAttendanceEntries { get; set; }
}
public class MeetingAttendanceEntry
{
public int Id { get; set; }
public int MeetingId { get; set; }
public Meeting Meeting { get; set; }
public int MeetingAttendeeId { get; set; }
public MeetingAttendee MeetingAttendee { get; set; }
public AttendanceStatus AttendanceStatus { get; set; }
}
The MeetingAttendee is set as:
modelBuilder.Entity<MeetingAttendee>().HasKey(pk => new { pk.MeetingId, pk.UserId });
modelBuilder.Entity<MeetingAttendee>().HasRequired(o => o.User).WithMany(m => m.MeetingAttendees).HasForeignKey(fk => fk.UserId);
modelBuilder.Entity<MeetingAttendee>().HasRequired(o => o.Meeting).WithMany(m => m.Attendees).HasForeignKey(fk => fk.MeetingId);
And when I'm trying to add MeetingAttendanceEntry, I'm getting "The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical" validation error.
I think is coming from the composite key, but everything I tried fails.
I tried from the parent entity:
modelBuilder.Entity<MeetingAttendee>().HasMany(m => m.MeetingAttendanceEntries).WithRequired(e => e.MeetingAttendee).HasForeignKey(e => e.MeetingAttendeeId);
From the child:
modelBuilder.Entity<MeetingAttendanceEntry>().HasRequired(e => e.MeetingAttendee).WithMany(m => m.MeetingAttendanceEntries).HasForeignKey(e => e.MeetingAttendeeId);
I tried adding the User and UserId to MeetingAttendanceEntry, and then setting it as FK as well:
modelBuilder.Entity<MeetingAttendanceEntry>().HasRequired(e => e.User).WithMany().HasForeignKey(e => e.UserId);
but still no luck.
What I'm missing?

Related

Apply cascade delete in one to many relationship

If I have two required foreign keys in class and these keys compose this class primary key and we have another class contain list of this class how to implement cascade delete in this case entity framework code first
public class Post
{
public int Id { get; set; }
public string ClientName { get; set; }
public JobType JobType { get; set; }
public double JobBudget { get; set; }
public DateTime CreationDate { get; set; }
public string JobDescription { get; set; }
public bool IsAccepted { get; set; }
public string ClientId { get; set; }
public List<Proposal> Proposals { get; set; }
public ApplicationUser Client { get; set; }
}
public class Proposal
{
public string FreelancerId { get; set; }
public int PostId { get; set; }
public bool IsAccepted { get; set; }
public ApplicationUser Freelancer { get; set; }
public Post Post { get; set; }
}
public PostConfigurations()
{
Property(p => p.ClientName)
.IsRequired();
Property(p => p.JobType)
.IsRequired();
Property(p => p.JobBudget)
.IsRequired();
Property(p => p.CreationDate)
.IsRequired();
Property(p => p.JobDescription)
.IsRequired()
.HasMaxLength(255);
HasOptional(p => p.Proposals)
.WithOptionalDependent()
.WillCascadeOnDelete(true)
}
public class ProposalConfigurations : EntityTypeConfiguration<Proposal>
{
public ProposalConfigurations()
{
HasKey(p => new { p.FreelancerId, p.PostId });
Property(p => p.FreelancerId)
.IsRequired();
Property(p => p.PostId)
.IsRequired();
}
}
I tried many things, but failed, can you please help?

EF6 Code first Composite Foreign key with Fluent API

I am having trouble creating One-one(zero) Foreign key relationship on code first EF6 fluent API
My Entities are
public class Invoice
{
public int AccountID { get; set; }
public int InvoiceID { get; set; }
public decimal Amount { get; set; }
public Refund Refund { get; set; }
internal static void ConfigureModel(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Invoice>()
.HasKey(e => new { e.AccountID, e.InvoiceID });
}
}
public class Refund
{
public int AccountID { get; set; }
public int RefundID { get; set; }
public decimal Amount { get; set; }
public int InvoiceID { get; set; }
public Invoice Invoice { get; set; }
internal static void ConfigureModel(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Refund>()
.HasKey(e => new { e.AccountID, e.RefundID });
modelBuilder.Entity<Refund>()
.HasRequired(e => e.Invoice )
// .HasForeignKey(e => new { e.AccountID, e.InvoiceID});
}
}
I can't define the composite foreign key on Refund table using fluent API
If I change the
public Refund Refund { get; set; }
to
public ICollection<Refund> Refund{ get; set; }
Then I can add this relation as
modelBuilder.Entity<Refund>()
.HasRequired(e => e.Invoice)
.WithMany(e => e.Refund)
.HasForeignKey(e => new { e.AccountID, e.InvoiceID});

EF7 Getting null values for entity's collection of entities which are many to many

I am getting null values for the collection of entities nested in my top entity. How do I properly write my LINQ query so that these values aren't null??
I am using Entity Framework 7 and MVC 6 Here are my classes:
My models:
public class WorkStation
{
public Id { get; set; }
public string Name{ get; set; }
public ICollection<PersonWorkStation> PersonWorkStations{ get; set; }
}
public class Person
{
public Id { get; set; }
public string FirstName { get; set; }
public ICollection<PersonWorkStation> PersonWorkStations{ get; set; }
}
public class PersonWorkStation
{
public int Id { get; set; }
public int PersonId { get; set; }
public Person Person { get; set; }
public int WorkStationId { get; set; }
public WorkStation WorkStation { get; set; }
}
My DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PersonWorkStation>()
.HasKey(op => new { op.Id });
modelBuilder.Entity<PersonWorkStation>()
.HasOne(pt => pt.Person)
.WithMany(p => p.PersonWorkStation)
.HasForeignKey(pt => pt.PersonId);
modelBuilder.Entity<PersonWorkStation>()
.HasOne(pt => pt.WorkStation)
.WithMany(t => t.PersonWorkStation)
.HasForeignKey(pt => pt.WorkStationId);
base.OnModelCreating(modelBuilder);
}
So with that being said, when I bring back a person, and look at the "PersonWorkStation"s collection, the WorkStation property is null. How can I bring back that entity?
Here is how I am retrieving the data:
var person = _context.Persons
.Include(p => p.PersonWorkStation)
.FirstOrDefault(p => p.Id == 1);
return person;
Again, the person.PersonWorkStations.Workstation entity is null for all items in the person.PersonWorkStations collection. How do I return this entity?
Thanks!
I have found the answer, I needed to add this line:
var person = _context.Persons
.Include(p => p.PersonWorkStation)
.ThenInclude(p => p.WorkStation)
.FirstOrDefault(p => p.Id == 1);
return person;

Linq doesn't want to cooperate - DbExpressionBinding error

I am trying to get something from my database, i need it to be like that:
var tribunalCase = context.TribunalCases.Where(c => c.Voters.Any(v => v.Voter.UserName == User.Identity.Name))
.Select(c => c)
.ToList();
But then, it crashes when i try to use .Any() or .All(). I get the following error:
DbExpressionBinding requires an input expression with a collection
ResultType.
Parameter name: input
This is my model:
public class Tribunal
{
public int Id { get; set; }
public Account User { get; set; }
public DateTime Expires { get; set; }
public Thread Thread { get; set; }
public int Points { get; set; }
public String Comment { get; set; }
public int VotersCount { get; set; }
public List<Voters> Voters { get; set; }
}
public class Voters
{
public int Id { get; set; }
public Account Voter { get; set; }
public bool Vote { get; set; }
public Tribunal Tribunal { get; set; }
}
Which i configured like that:
modelBuilder.Entity<Tribunal>()
.HasOptional(t => t.Voters)
.WithRequired();
How can i fix this error?
Configuration is incorrect: Voters is a collection, so you should call HasMany, not HasOptional.

Entity framework to object with collection, with Automapper, exception on update

I have an EF 4.1 model, two tables are generated PERSON and ADDRESS from my database.
//This method works
public void Update(IPerson person)
{
var personDb = _dataContext.PERSON.SingleOrDefault(x => x.ID == person.Id);
Mapper.Map<Person, PERSON>((Person)person, personDb);
_dataContext.SaveChanges();
}
But when I remove the .Ignore() in Automapper mapping, I get this exception :
The EntityCollection could not be initialized because the relationship manager for the object to which the EntityCollection belongs is already attached to an ObjectContext. The InitializeRelatedCollection method should only be called to initialize a new EntityCollection during deserialization of an object graph.
I'd like when I added an new address to the existing addresses save the person and address.
Any idea ?
Thanks,
public void AutomapperInit()
{
Mapper.CreateMap<Person, PERSON>()
.ForMember(x => x.ADDRESS, opt => opt.Ignore());
Mapper.CreateMap<PERSON, Person>()
.ForMember(dest => dest.Address, option => option.MapFrom(src => src.ADDRESS.Select(address => Mapper.Map<ADDRESS, Address>(address)).ToList()));
Mapper.CreateMap<Address, ADDRESS>();
Mapper.CreateMap<ADDRESS, Address>()
.ForMember(dest => dest.Rue, option => option.MapFrom(src => src.STREET));
}
public interface IPerson
{
int Id { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
ICollection<IAddress> Address { get; set; }
}
public interface IAddress
{
string Rue { get; set; }
string Number { get; set; }
int PersonId { get; set; }
}
class Person : IPerson
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<IAddress> Address { get; set; }
}
class Address : IAddress
{
public string Rue { get; set; }
public string Number { get; set; }
public int PersonId { get; set; }
}
Does
var personDb = Mapper.Map<Person, PERSON>((Person)person, personDb);
_dataContext.Attach(personDb);
_dataContext.SaveChanges();
give the results you expect, or am I misinterpreting your question?

Resources