multiple relationships with same table by Dataannotation with code first - ef-code-first

I have the following model:
public class Member
{
public int Id { get; set; }
public string Username { get; set; }
public int MainEmailId { get; set; }
public virtual Email MainEmail { get; set; }
public virtual ICollection<Email> MemberEmails { get; set; }
}
public partial class Email
{
public Int32 Id { get; set; }
public String Email { get; set; }
public int MemberId { get; set; }
public virtual Member Member { get; set; }
}
As you can see I wish to create a:
one-to-one relation from the Member to MemberEmail (the main email address)
one-to-many relation from Member to MemberEmail
I know how to do this with Code First Fluent API. However I need to do it with DataAnnotations only. Is this possible?
Thanks a lot.

Related

How can I set up two navigation properties of the same type in Entity Framework without use Fluent API

i'm trying create DB using codefirst. i want to create two ForeingKey from same table. But when i set up two navigation properties of the same type, get error like :
The foreign key name 'FollowedUser' was not found on the dependent type Models.UserUserWatchListItem'. The Name value should be a comma separated list of foreign key property names.
public class UserUserWatchListItem
{
public int Id { get; set; }
[Key,ForeignKey("FollowedUser")]
public virtual User FollowedUser { get; set; }
public int FollowedUserId { get; set; }
[Key,ForeignKey("FolloweeUser")]
public int FolloweeUserId { get; set; }
public virtual User FolloweeUser { get; set; }
}
Use this :
public class UserUserWatchListItem
{
public int Id { get; set; }
public int FollowedUserId { get; set; }
public int FolloweeUserId { get; set; }
[ForeignKey("FollowedUser")]
[InverseProperty("FollowedUsers")]
public virtual User FollowedUser { get; set; }
[ForeignKey("FolloweeUser")]
[InverseProperty("FolloweeUsers")]
public virtual User FolloweeUser { get; set; }
}
public class User
{
...
[InverseProperty("FollowedUser")]
public virtual ICollection<UserUserWatchListItem> FollowedUsers { get; set; }
[InverseProperty("FolloweeUser")]
public virtual ICollection<UserUserWatchListItem> FolloweeUsers { get; set; }
}

Unable to add second self Referencing FK to model, causes Unable to determine the principal end error

First off, I know there are a lot of posts about the Unable to determine the principal end of an association between the types error but ever single one I see does not match my issue, if I missed one sorry about that.
I have built an Entity that will end up referencing it's self twice and when I put the code in for the first self reference it works fine, as soon as ad the code for the second it breaks. Doing some testing I have found that if I use either of the self references by them self everything works fine, it is only when I add the second self reference that it breaks. The code I am using for the self references is:
[ForeignKey("ManagerID")]
public User Manager { get; set; }
//Auditing Fields
public DateTime DateCreated { get; set; }
public int? UpdatedByUserID { get; set; }
public DateTime? DateUpdated { get; set; }
public DateTime LastAutoUpdate { get; set; }
[ForeignKey("UpdatedByUserID")]
public User UpdatedByUser { get; set; }
The full entity code block is:
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public int ADPFileNumber { get; set; }
[Required]
public string ADUserName { get; set; }
public int AirCardCheckInLateCount { get; set; }
[Required]
public string Email { get; set; }
public DateTime? EndDate { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public int ManagerID { get; set; }
public string MobilePhone { get; set; }
[Required]
public string Office { get; set; }
[Required]
public string Phone { get; set; }
public decimal PTO { get; set; }
public DateTime StartDate { get; set; }
public int VehicleCheckInLateCount { get; set; }
public int WexCardDriverID { get; set; }
[ForeignKey("ManagerID")]
public User Manager { get; set; }
//Auditing Fields
public DateTime DateCreated { get; set; }
public int? UpdatedByUserID { get; set; }
public DateTime? DateUpdated { get; set; }
public DateTime LastAutoUpdate { get; set; }
[ForeignKey("UpdatedByUserID")]
public User UpdatedByUser { get; set; }
}
What am I missing that cause the second self reference to break?
You have to indicate the principal end of both associations explicitly. You can do that with the class you had originally, without inverse collection properties:
modelBuilder.Entity<User>()
.HasOptional(u => u.Manager)
.WithMany()
.HasForeignKey(u => u.ManagerID);
modelBuilder.Entity<User>()
.HasOptional(u => u.UpdatedByUser)
.WithMany()
.HasForeignKey(u => u.UpdatedByUserID);
Note that ManagerID should be an int? as well. You can't create any User if it requires another user to preexist. That's a chicken-and-egg problem.
As mentionned in Multiple self-referencing relationships in Entity Framework, you seem to be missing the other part of the relationship.
i.e.
[InverseProperty("Manager")]
public virtual ICollection<User> ManagedUsers {get;set;}
[InverseProperty("UpdatedByUser")]
public virtual ICollection<User> UpdatedUsers {get;set;}
EDIT: based on #Gert Arnold's answer you should indeed add the [InverseProperty] attribute

Parent and child record added on single MVC View

In ASP.NET MVC 5 and EF6 Code First, i have a case in which a student can have one to many addresses. Now i want to use Student model in View to add both the record Student and Addresses of student. But the problem is i cant add addresses of student, is there any appropriate solution for this solution
Here is the example code
public class Student
{
public Student()
{ }
[Key]
public int StudentID { get; set; }
[Required]
public string Name { get; set; }
public virtual List<Address> Address { get; set; }
}
public class Address
{
public Address()
{
}
[Key]
public int AddressID { get; set; }
[ForeignKey("Student")]
public int StudentID { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string PostalCode { get; set; }
public string State { get; set; }
public string City { get; set; }
public string Country { get; set; }
public virtual Student Student { get; set; }
}
Make Listbox for address's and Pass with List that will be really help you and can you paste controller code here?

Allow null in model when using Code first

I have an model like this:
public class EquipmentEmployee
{
public int EquipmentEmployeeID { get; set; }
public int EmployeeID { get; set; }
public Employee Employee { get; set; }
public int EquipmentID { get; set; }
public Equipment Equipment { get; set; }
public int RequisitionID { get; set; }
public Requisition Requisition { get; set; }
public DateTime From { get; set; }
public DateTime To { get; set; }
public string Comment { get; set; }
}
I use Mvc scaffolding for creating my controllers, repositories and views. Int the create View I'm not able to POST since I dont have values for "to" and "RequisitionID". I have not added [Required] to them. Is this possible? To POST and have those two null?
You should declare optional fields using a nullable type
public int? RequisitionID { get; set; }
To accept the null values you can use the following solution.
public int? RequisitionID { get; set; }

Model collections of the same class held by several other classes

How do I model the following using Castle ActiveRecord?
I have two classes, Customer and Task.
I would like to reuse a third class, Note, stored in a Collection in each of the Customer and Task classes.
public class Note
{
public int ID { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
}
public class Customer
{
public int ID { get; set; }
public IList<Note> Notes { get; set; }
}
public class Task
{
public int ID { get; set; }
public IList<Note> Notes { get; set; }
}
I would then like to be able to pass the Notes collection to a Gridview, Listview or Repeater in the relevant ASP.Net page for the Customer or Task classes.
I think what you need is to implement a type hierarchy. You can read about it here.
We settled on the following pattern:
[ActiveRecord]
public class Note
{
[PrimaryKey]
public int ID { get; set; }
[Property]
public string Subject { get; set; }
[Property]
public string Body { get; set; }
[BelongsTo]
public Customer Customer { get; set; }
[BelongsTo]
public Customer Task{ get; set; }
}
[ActiveRecord]
public class Customer
{
[PrimaryKey]
public int ID { get; set; }
[HasMany]
public IList<Note> Notes { get; set; }
}
[ActiveRecord]
public class Task
{
[PrimaryKey]
public int ID { get; set; }
[HasMany]
public IList<Note> Notes { get; set; }
}

Resources