One to Many Assosiation without a collection on many Side EF - asp.net

I have a BaseEntity Like This :
public class BaseEntity<T>
{
public BaseEntity()
{
this.createdDate = System.DateTime.Now;
this.updatetdDate = System.DateTime.Now;
}
[System.ComponentModel.DataAnnotations.Key]
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.Schema.Column("ID")]
[System.ComponentModel.DataAnnotations.Schema.
DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public T id { get; set; }
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.Schema.ForeignKey("Created_by")]
public virtual BonchaghWebApplication.Models.Core.User createdBy { get; set; }
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.Schema.ForeignKey("Updated_by")]
public virtual BonchaghWebApplication.Models.Core.User updatedBy { get; set; }
[System.ComponentModel.DataAnnotations.Required]
public DateTime createdDate { get; set; }
[System.ComponentModel.DataAnnotations.Required]
public DateTime updatetdDate { get; set; }
}
}
and another like this :
[System.ComponentModel.DataAnnotations.Schema.Table("App_User")]
public class User:BaseEntity<long>
{
public String userName { get; set; }
public String password { get; set; }
}
and these two have one to many relation, I don't need a collection on user side, I say that the record saved by a user and it doesn't matter the user save witch records

Related

Expression of type 'System.Collections.Generic.List`1[API.Entities.CompanySetting]' cannot be used for parameter of type 'System.Linq.IQueryable

I am trying to find a simple way using AutoMapper to return all companies that are linked to a specific User Id in a many-to-many relationship scenario. I followed the SO Automapper many to many mapping but I get the error message "Expression of type 'System.Collections.Generic.List`1[API.Entities.CompanySetting]' cannot be used for parameter of type 'System.Linq.IQueryable" when trying to follow the logic.
My AppUser entity:
public class AppUser
{
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<AppUserCompanySetting> AppUserCompanySettings { get; set; } = new List<AppUserCompanySetting>();
}
My CompanySetting entity:
public class CompanySetting
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string CompanyRegistrationNumber { get; set; }
public bool isActive { get; set; }
public bool isArchived { get; set; }
public virtual ICollection<AppUserCompanySetting> AppUserCompanySettings { get; set; } = new List<AppUserCompanySetting>();
}
And I have the Join table
public class AppUserCompanySetting
{
public int AppUserId { get; set; }
public virtual AppUser AppUser { get; set; }
public int CompanySettingsId { get; set; }
public virtual CompanySetting CompanySettings { get; set; }
}
I then created a CompanySettingDto
public class CompanySettingDto
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string CompanyRegistrationNumber { get; set; }
public bool isActive { get; set; }
public bool isArchived { get; set; }
}
And a MemberDto:
public class MemberDto
{
public int Id { get; set; }
public string Username { get; set; }
public string PhotoUrl { get; set; }
public string KnownAs { get; set; }
public int TimeActive { get; set; }
public DateTime LastActive {get; set;}
public ICollection<PhotoDto> Photos { get; set; }
public ICollection<CompanySettingDto> CompanyInformation { get; set; }
}
I then tried Automapper to bring the relationships between the User and the Company Information I require:
public class AutoMapperProfiles : Profile
{
public AutoMapperProfiles()
{
CreateMap<AppUser, MemberDto>()
.ForMember(dest => dest.CompanyInformation, opt => opt.MapFrom(x => x.AppUserCompanySettings.Select(y => y.CompanySettings).ToList()))
CreateMap<CompanySetting, CompanySettingDto>();
}
}
I am writing an API call to get all companies that are linked to a specific UserId.
public async Task<IEnumerable<MemberDto>> GetCompaniesByUserIdAsync(int userId)
{
return await _context.Users
.Where(x => x.Id == userId)
.ProjectTo<MemberDto>(_mapper.ConfigurationProvider)
.ToListAsync();
}

Code First Model Definition

I have the following models,do I define it Ok?
User is the main Entity and can have 0..1 to * (zero /one to many relationship ) address.
2.User can have have 0..1 to 1 (one to one userPass )
This is the main table
public class User
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string PhoneWork { get; set; }
public string WorkingAt { get; set; }
public virtual UserPass UserPass { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class ConfigModelDbContext : DbContext
{
public DbSet<User> User { get; set; }
public DbSet<Address> Addresses { get; set; }
public DbSet<UserPass> UserPasses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<User>()
.HasOptional(c => c.Addresses).WithRequired(addresses => new User());
modelBuilder.Entity<User>()
.HasOptional(c => c.UserPass).WithRequired(pass => new User());
}
}
Address Class
public class Address
{
[Key]
[ForeignKey("User")]
public string UserId { get; set; }
public string UserAddress { get; set; }
}
Userpass class
public class UserPass
{
[Key]
[ForeignKey("User")]
public string UserId { get; set; }
public string User { get; set; }
public string Password { get; set; }
}
i also created classes same as above but can it create relationship directly on database table?
at first I offer you to use data annotation instead of fluent api always.
then correct AddressClass like below:
public class Address
{
[Key]
public int Id { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
public string UserId { get; set; }
public string UserAddress { get; set; }
}
This will create Ralationship.
for more details please read Code First DataAnnotations

Save Relation between User and Entity in ASP.NET MVC4

I have an Exercise entity defined in my ASP.NET MVC4 Web Application.
I'm using the Form Authentication with the default AccountModels.cs class.
I have class which looks like
public class Exercise
{
private DateTime _DateCreated = DateTime.Now;
private UserProfile _Teacher;
public int Id{ get; set; }
public string Question { get; set; }
public int Anwser { get; set; }
public string Category { get; set; }
public int maxNbrOfAttempts { get; set; }
public string Hints { get; set; }
public virtual ICollection<Quiz> Quizzes { get; set; }
public DateTime Date
{
get { return _DateCreated; }
set { _DateCreated = value; }
}
public UserProfile Author
{
get { return _Teacher; }
set { _Teacher = value; }
}
}
Am I using the UserProfile correctly to link between an Exercise and a logged in user?
How can I get the current UserProfile in my controller?
Change it like this:
public class Exercise
{
public Exercise()
{
this.Date = DateTime.Now;
this.Author = User.Identity.Name; //Write this line if you want to set
//the currently logged in user as the Author
public int Id{ get; set; }
public string Question { get; set; }
public int Anwser { get; set; }
public string Category { get; set; }
public int maxNbrOfAttempts { get; set; }
public string Hints { get; set; }
public virtual ICollection<Quiz> Quizzes { get; set; }
public virtual DateTime Date { get; set; }
public virtual UserProfile Author { get; set; }
}

How to Update model and database with code first approach in Asp.net MVC

I'm new to mvc. I've creted an MVC app, in which i have used code first approach. Right now i have two tables Deal and Comment. Now i want to add a new table Category in the database and new column categoryId in Deal table.
How i can update database and model?
I'm using Sql Server 2008 R2 for Database.
I've following structure of class:
namespace FBWebApp.Models
{
public class Deal
{
public int ID { get; set; } // ID
public string Title { get; set; } // Titolo del deal
public string Description { get; set; } // Descrizione dell'annuncio
public string FacebookUID { get; set; } // UID facebook dell'utente
public string Visibility { get; set; } // Visibility
public string Category { get; set; }
public int Option1 { get; set; }
public int Option2 { get; set; }
public int Option3 { get; set; }
public int Option4 { get; set; }
public string PhotoURL { get; set; } // URL of the facebook photo profile
public string Name { get; set; } // Name of the user
public string ProfileUrl { get; set; } // URL of the facebook profile
public string Photo1 { get; set; } // URL of the Photo1 (local )
public string Photo2 { get; set; }
public string Photo3 { get; set; }
public string Photo4 { get; set; }
public string Photo5 { get; set; }
}
public class Comment
{
[Key]
public int CommentId { get; set; }
public string CommentText { get; set; }
public int ID { get; set; }
[ForeignKey("ID")]
public Deal DelNav { get; set; }
}
public class DealDBContext : DbContext
{
public DealDBContext() : base("DealDBContext") { }
public DbSet<Deal> Deals { get; set; }
public DbSet<Comment> Comments { get; set; }
}
}
Try using 'update-database -force -verbose' in the Package Manager Console.
If it doesn't work, modify the migration but typing 'add-migration somename' and it will apear in the Migrations folder.
If you are new to MVC and EF, definitely check out this tutorial. It explains all about that and everything else you need to know:
http://pluralsight.com/training/Player?author=scott-allen&name=mvc4-building-m1-intro&mode=live&clip=0&course=mvc4-building
first add your model :
public class Category
{
public int ID { get; set; }
public int cateName { get; set; }
}
in Deal class :
public class Deal
{
//..
[ForeignKey("CatId")]
public virtual Category Category { get; set; }
}
after Enable Migration you should use this command in console manager to update your database :
update-database

convert ASp.net membership provider classes to code first entities in entity framework

I am using entity frame work code first approach to design my web application in asp.net 4.5.
I have converted all asp.net membership related tables in code first entities as below
public class Application
{
public string ApplicationName { get; set; }
[Key]
public System.Guid ApplicationId { get; set; }
public string Description { get; set; }
public virtual ICollection<Membership> Memberships { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class Membership
{
[ForeignKey("Application")]
public System.Guid ApplicationId { get; set; }
[Key, ForeignKey("User")]
public System.Guid UserId { get; set; }
public string Password { get; set; }
public int PasswordFormat { get; set; }
public string PasswordSalt { get; set; }
public string Email { get; set; }
public string PasswordQuestion { get; set; }
public string PasswordAnswer { get; set; }
public bool IsApproved { get; set; }
public bool IsLockedOut { get; set; }
public System.DateTime CreateDate { get; set; }
public System.DateTime LastLoginDate { get; set; }
public System.DateTime LastPasswordChangedDate { get; set; }
public System.DateTime LastLockoutDate { get; set; }
public int FailedPasswordAttemptCount { get; set; }
public System.DateTime FailedPasswordAttemptWindowStart { get; set; }
public int FailedPasswordAnswerAttemptCount { get; set; }
public System.DateTime FailedPasswordAnswerAttemptWindowsStart { get; set; }
public string Comment { get; set; }
public virtual Application Application { get; set; }
public virtual User User { get; set; }
}
public class Profile
{
[Key, ForeignKey("User")]
public System.Guid UserId { get; set; }
public string PropertyNames { get; set; }
public string PropertyValueStrings { get; set; }
public byte[] PropertyValueBinary { get; set; }
public System.DateTime LastUpdatedDate { get; set; }
public virtual User User { get; set; }
}
public class Role
{
[ForeignKey("Application")]
public System.Guid ApplicationId { get; set; }
[Key]
public System.Guid RoleId { get; set; }
public string RoleName { get; set; }
public string Description { get; set; }
public virtual Application Application { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class User
{
[ForeignKey("Application")]
public System.Guid ApplicationId { get; set; }
[Key]
public System.Guid UserId { get; set; }
public string UserName { get; set; }
public bool IsAnonymous { get; set; }
public System.DateTime LastActivityDate { get; set; }
public virtual Application Application { get; set; }
public virtual Membership Membership { get; set; }
public virtual Profile Profile { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
My Datacontext and initalizer classes are as below
public class TrainningInitializer : DropCreateDatabaseIfModelChanges<TrainningContext>
{
protected override void Seed(TrainningContext context)
{
}
}
public partial class TrainningContext : DbContext
{
public TrainningContext()
: base("name=TrainningContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
public DbSet<Application> Applications { get; set; }
public DbSet<Membership> Memberships { get; set; }
public DbSet<Profile> Profiles { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<User> Users { get; set; }
}
I am setting Initializer as below in application_start event inside Global.asax.
Database.SetInitializer<TrainningContext>(new TrainningInitializer());
But when I am running my application I am getting below error
Introducing FOREIGN KEY constraint 'FK_dbo.RoleUsers_dbo.Users_User_UserId' on table 'RoleUsers' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.
Can someone please help in correcting my entity classes.
When you delete an Application entity this delete cascades to the Roles and the Users and then from Roles to the RoleUsers join table and from the Users to RoleUsers. Those two delete paths from Application to RoleUsers table are the "multiple cascade paths" the exception is talking about. They are not allowed in SQL Server.
Cascading delete is enabled by default for the Roles and Users relationships of Application because the foreign key ApplicationId in these two tables is not nullable, hence the relationship is required. Required relationships have cascading delete turned on by default.
But you can turn it off with Fluent API:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Application>()
.HasMany(a => a.Roles)
.WithRequired(r => r.Application)
.HasForeignKey(r => r.ApplicationId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Application>()
.HasMany(a => a.Users)
.WithRequired(u => u.Application)
.HasForeignKey(u => u.ApplicationId)
.WillCascadeOnDelete(false);
}
(It's probably sufficient for one of the two.)
If you would delete an Application entity now, you need to delete the related Roles and Users as well. The database won't do that automatically for you anymore.

Resources