Bind one-many relation model in the view in MVC - entity-framework

I have a user registration page where i uses a tabbed layout.In the first tab i will enter the personal details and in the second tab I want to enter a couple of references provied by the user.
I have created a viewmodel and binded the viewmodel to the View.The problem is i cannot access properties in the Relation class in the View
I am using two simple models
public partial class WalkInn
{
public WalkInn()
{
this.tblWalkIn_Relation = new HashSet<WalkIn_Relation>();
}
public long WALKINID { get; set; }
public long LOGINID { get; set; }
public string CANDIDATE_NAME { get; set; }
public string FATHER_SPOUSE_NAME { get; set; }
public System.DateTime DOB { get; set; }
public virtual Login tblLogin { get; set; }
public virtual ICollection<WalkIn_Relation> tblWalkIn_Relation { get; set; }
}
public partial class WalkIn_Relation
{
public long RELATIONID { get; set; }
public long WALKINID { get; set; }
public string NAME { get; set; }
public string RELATION { get; set; }
public virtual WalkInn tblWalkInn { get; set; }
}
Viewmodel is as follows
public class WalkInnVM
{
public WalkInn WalkInn { get; set; }
public ICollection<WalkIn_Relation> WalkInRelation { get; set; }
}
View is as follows
#model CRM.Models.ViewModels.WalkInnVM
#{
ViewBag.Title = "Add2";
}
<h2>Add WalkInn</h2>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Name</label>
#Html.TextBoxFor(model=>model.WalkInn.CANDIDATE_NAME)
**Cannot access the below code**
#Html.TextBoxFor(model=>model.WalkInn_Relation.Name)

Related

EF Core 2.1. Loading nested entities with joining tables

I have these models:
public class Transfer
{
public Article Article { get; set; }
public Branch BranchFrom { get; set; }
public Branch BranchTo { get; set; }
public User User { get; set; }
}
public class Article
{
public int Id{ get; set; }
public string Description { get; set; }
}
public class Branch
{
public int Id { get; set; }
public string Address { get; set; }
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
I need to get a list of all transfers made by a specific user, and load all it's related entities (BranchFrom, BranchTo, Article, User).
In EF 6 I was able to do it easily with this code:
_dbContext.Transfer.Include(x=>x.BranchFrom).Include(x=>x.BranchTo).Include(x=>x.Article).Include(x=>x.User).Where(x=>x.User.Id == userId).ToListAsync();
Given that in EF Core 2.1 you must define the joining tables I added them as follows:
public class TransferUser
{
public int TransferId { get; set; }
public int UserId { get; set; }
public Transfer Transfer { get; set; }
public User User { get; set; }
}
public class TransferArticle
{
public int TransferId { get; set; }
public int ArticleId { get; set; }
public Transfer Transfer { get; set; }
public Article Article { get; set; }
}
public class TransferBranchFrom
{
public int TransferId { get; set; }
public int BranchId { get; set; }
public Transfer Transfer { get; set; }
public Branch Branch { get; set; }
}
public class TransferBranchTo
{
public int TransferId { get; set; }
public int BranchId { get; set; }
public Transfer Transfer { get; set; }
public Branch Branch { get; set; }
}
And because of that I modified the Transfer model to be like this:
public class Transfer
{
public TransferArticle TransferArticle { get; set; }
public TransferBranch TransferBranchFrom { get; set; }
public TransferBranch TransferBranchTo { get; set; }
public TransferUser TransferUser { get; set; }
}
Now I don't know how the query needs to be.
I was doing it like this and it works, but only loads the transfer and the user
_dbContext.Transfer.Include(x=>x.TransferUser).Where(x=>x.TransferUser.UserId == userId).ToListAsync();
When I add another table then it doesnt work and throws an exception:
_dbContext.Transfer.Include(x=>x.TransferUser).Include(x=>x.TransferBranchFrom).Where(x=>x.TransferUser.UserId == userId).ToListAsync();
I cannot find any examples on how to load all the entities for this scenario

EF Code First 6 and many-to-many with entity mapping

Following the example in this question: How to create a many-to-many mapping in Entity Framework? I would like to have a table mapping where I can add or remove many-to-many relationships without having to go through the Media or Contract entities.
Essentially, I would like to have:
public class Media // One entity table
{
public int Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
}
public class Contract // Second entity table
{
public int Id { get; set; }
public string Code { get; set }
public virtual ICollection<Media> Medias { get; set; }
}
public class ContractMedia // Association table implemented as entity
{
public Media Media { get; set; }
public int MediaId { get; set; }
public Contract Contract { get; set; }
public int ContractId { get; set; }
}
Is it possible to configure this scenario using the FluentAPI?
afaik not with the ContractMedia entity, but you can:
public class Media // One entity table
{
public int Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
public virtual ICollection<ContractMedia> Contracts { get; set; }
}
public class Contract // Second entity table
{
public int Id { get; set; }
public string Code { get; set }
public virtual ICollection<ContractMedia> Medias { get; set; }
}
public class ContractMedia // Association table implemented as entity
{
public Media Media { get; set; }
public int MediaId { get; set; }
public Contract Contract { get; set; }
public int ContractId { get; set; }
}
or
public class Media // One entity table
{
public int Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
}
public class Contract // Second entity table
{
public int Id { get; set; }
public string Code { get; set }
public virtual ICollection<Media> Medias { get; set; }
}
that will lead to the creation of a non mapped association table in the database.

EF6 generates all the entity classes (tt .cs) in single file (eg. model.cs) and not as separate .cs file

I am using EF6. I have 2 tables Events and Users for which I used database first approach to generate the EDMX models and entity classes. Everything works fine but the entity classes are coming under a single file in this case EventSample.cs(shown below). I am not getting separate files for each entity as Event.cs and User.cs. Please let me know if this is correct and if not how to rectify it?
public partial class Event
{
public Event()
{
this.Users = new HashSet<User>();
}
public int Id { get; set; }
public string Title { get; set; }
public System.DateTime Time { get; set; }
public string Location { get; set; }
public string Description { get; set; }
public int Creator_Id { get; set; }
public virtual User User { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public partial class User
{
public User()
{
this.Events = new HashSet<Event>();
this.Events1 = new HashSet<Event>();
}
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public virtual ICollection<Event> Events { get; set; }
public virtual ICollection<Event> Events1 { get; set; }
}

EF Data Annotation - Foreign Key - How to Customize

My issue is the following. I have a Model for an Address table as follows.
public partial class ADDRESS
{
public ADDRESS()
{
this.ADDRESS_ID = Guid.NewGuid();
}
public Guid ADDRESS_ID { get; set; }
public string ADDRESS_LINE { get; set; }
public string CITY { get; set; }
public Guid? STATE_ID { get; set; }
public string ZIP { get; set; }
}
This ADDRESS model is used throughout my application and has different validation requirements depending on where it is placed within a form.
I am wondering if there is a way to customize the data annotations. For example, the ADDRESS_LINE and CITY properties are required for OCCUPATION_ADDRESS but not required for WORK_LOCATION_ADDRESS.
public class OCCUPATION_DETAILS
{
public string COMPANY_NAME { get; set; }
public string JOB_TITLE { get; set; }
etc...
public Guid OCCUPATION_ADDRESS_ID { get; set; }
public virtual ADDRESS OCCUPATION_ADDRESS { get; set; }
public WORK_LOCATION_ID { get; set; }
public virtual ADDRESS WORK_LOCATION_ADDRESS { get; set; }
}
Or it could be that basic validation is the same (zip has to be 5 digits), but I need to adjust the "DisplayName" that is used to match the label of the form it is within.
Trying to minimize the amount of copied models I have set up; otherwise maintenance will be a nightmare.
you can achieve this by using the idea of inheritance
how?
public abstract class ADDRESS
{
public ADDRESS()
{
this.ADDRESS_ID = Guid.NewGuid();
}
public Guid ADDRESS_ID { get; set; }
public string ADDRESS_LINE { get; set; }
public string CITY { get; set; }
public Guid? STATE_ID { get; set; }
public string ZIP { get; set; }
}
public parital class OCCUPATION_ADDRESS: ADDRESS,IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(string.IsNullOrWhiteSpace(ADDRESS_LINE))
yield return new ValidationResult("Address line is required!",new string[]{"ADDRESS_LINE"});
}
}
public parital class WORK_LOCATION_ADDRESS: ADDRESS,IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
}
}
// and your Occupation details class will be like: instead of ADDRESS you will use the corresponding derived classes
public class OCCUPATION_DETAILS
{
public string COMPANY_NAME { get; set; }
public string JOB_TITLE { get; set; }
etc...
public Guid OCCUPATION_ADDRESS_ID { get; set; }
public virtual OCCUPATION_ADDRESS OCCUPATION_ADDRESS { get; set; }
public WORK_LOCATION_ID { get; set; }
public virtual WORK_LOCATION_ADDRESS WORK_LOCATION_ADDRESS { get; set; }
}
and the inheritance should be Table per Hierarchy (TPH)
for more information about TPH check this Table per hierarchy
hope that this will help you
regards

Eager Load Entity Framework Navigation Property error

I'm trying to eager load some child entities like so:
_context.Sites.Where(x => x.ID == siteID).Include(s => s.SiteLoggers).FirstOrDefault();
However, the error I am getting is:
A specified Include path is not valid. The EntityType 'MyProject.Dal.EF.Site' does not declare a navigation property with the name 'SiteLoggers'.
What is saying is correct, as MyProject.Dal.EF.Site does not exist, the object exists in MyProject.Domain.Entities.Site
What am I missing??? Thanks!
POCOs:
namespace MyProject.Domain.Entities
{
public class Site
{
public int ID { get; set; }
public int LocationID { get; set; }
public bool Active { get; set; }
public bool Deleted { get; set; }
public string Name { get; set; }
public virtual Location Location { get; set; }
public virtual IEnumerable<SiteLogger> SiteLoggers { get; set; }
}
}
namespace MyProject.Domain.Entities
{
public class SiteLogger
{
public int ID { get; set; }
public int UID { get; set; }
public int SiteID { get; set; }
public string Name { get; set; }
public int LocationID { get; set; }
public bool Active { get; set; }
public bool Deleted { get; set; }
public virtual Site Site { get; set; }
public virtual Location Location { get; set; }
}
}
You need to use ICollection instead of IEnumerable, because EF requires that your navigation properties are defined as ICollection<T>.
public virtual ICollection <SiteLogger> SiteLoggers { get; set; }