Scaffolding model with inheritance in ASP.NET MVC 3 and Entity Framework - asp.net

I'm trying out the new scaffolding features in MVC 3, using Entity Framework Code First. My model looks like this:
public abstract class A
{
public int Id { get; set; }
}
public class B : A
{
public string Name { get; set; }
}
public class MyContext : DbContext
{
public DbSet<A> As { get; set; }
}
I create a new controller using the new controller wizard in MVC and select to scaffold type A. CRUD code is generated and I can successfully start the project in a webbrowser. When I try to create a new A, I get the following error message:
"Cannot create an abstract class"
which makes sense. A is abstract.
Can I use scaffolding to create B's and other inherited classes from A?

AFAIK you should add a
using System.ComponentModel.DataAnnotations;
[Table("TableNameForB")]
public class B : A
{
public string Name { get; set; }
}
as attribute for your concrete class
Find here a complete example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
namespace ZooLabPoco
{
public class Context : DbContext
{
public DbSet<Animal> Animals { get; set; }
public DbSet<Zoo> Zoos { get; set; }
}
public class Zoo
{
public int Id { get; set; }
public virtual ICollection<Animal> Animals { get; set; }
public Zoo()
{
this.Animals = new List<Animal>();
}
}
public abstract class Animal
{
public int Id { get; set; }
public int ZooId { get; set; }
public virtual Zoo Zoo { get; set; }
}
[Table("Lions")]
public class Lions : Animal
{
public string LionName { get; set; }
}
[Table("Tigers")]
public class Tigers : Animal
{
public string TigerName { get; set; }
public int TailLength { get; set; }
}
class Program
{
static void Main(string[] args)
{
var context = new Context();
context.Database.Delete();
context.Database.CreateIfNotExists();
var zoo = new Zoo();
zoo.Animals.Add(new Lions { LionName = "Fritz" });
zoo.Animals.Add(new Lions { LionName = "Jerry" });
zoo.Animals.Add(new Tigers { TigerName = "Pluto" });
context.Zoos.Add(zoo);
context.SaveChanges();
}
}
}

Related

How to create a list page for Users in .Net Core 2

We extended the Identity Roles as well Users:
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AthlosifyWebArchery.Models
{
public class ApplicationRole : IdentityRole
{
public ApplicationRole() : base() { }
public ApplicationRole(string roleName) : base(roleName) { }
public ApplicationRole(string roleName, string description, DateTime createdDate) : base(roleName)
{
base.Name = roleName;
this.Description = description;
this.CreatedDate = createdDate;
}
public string Description { get; set; }
public DateTime CreatedDate { get; set; }
}
}
and
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace AthlosifyWebArchery.Models
{
public class ApplicationUser : IdentityUser
{
public ApplicationUser() : base() { }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string Suburb { get; set; }
public string State { get; set; }
public string Postcode { get; set; }
public string Country { get; set; }
[InverseProperty("ApplicationUser")]
public IList<HostApplicationUser> HostApplicationUsers { get; set; }
[InverseProperty("HostApplicationCreatedUser")]
public HostApplicationUser HostApplicationCreatedUser { get; set; }
[InverseProperty("HostApplicationLastModifiedUser")]
public HostApplicationUser HostApplicationLastModifiedUser { get; set; }
[InverseProperty("ApplicationUser")]
public IList<ClubApplicationUser> ClubApplicationUsers { get; set; }
[InverseProperty("ClubApplicationCreatedUser")]
public ClubApplicationUser ClubApplicationCreatedUser { get; set; }
[InverseProperty("ClubApplicationLastModifiedUser")]
public ClubApplicationUser ClubApplicationLastModifiedUser { get; set; }
}
}
We are trying to create a Razor Page list of users as well their role:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using AthlosifyWebArchery.Data;
using AthlosifyWebArchery.Models;
using Microsoft.AspNetCore.Identity;
namespace AthlosifyWebArchery.Pages.Administrators.Users
{
public class IndexModel : PageModel
{
private readonly AthlosifyWebArchery.Data.ApplicationDbContext _context;
public IndexModel(AthlosifyWebArchery.Data.ApplicationDbContext context)
{
_context = context;
}
public List<ApplicationUser> User { get; private set; }
public List<IdentityUserRole<string>> UsersRoles { get; set; } // get my roles or context of user
public List<IdentityRole> AllRoles { get; private set; }
public async Task OnGetAsync()
{
User = _context.Users.Include("UserRoles").ToList();
//UsersRoles = _context.UserRoles.ToList(); // get my roles or context of user
//AllRoles = _context.Roles.ToList();
}
}
}
We managed to get just the user list BUT not sure on how to include the Roles in this case.
Any pointer please?
Firstly, try to avoid using Include function's string overload. Using the lamda instead will help you be sure that the property exists. For instance, in this case, a property named UserRoles doesn't exist for your user class in the first place. Secondly, the syntax you are trying to use it generally used for a one to many relationships. Note that users and roles is a many to many relation and the identity context (that your dbcontext extended) has a UserRoles property for this. You should be able to get all users joined with their roles using a query like this:
IEnumerable<User> users = from u in context.Users
from r in context.Roles
from ur in context.UserRoles
where u.Id == ur.UserId && ur.RoleId == r.Id
select u;

create Multiple tables using Sqlite-net-pcl

I am using xamarin forms and Sqlite-net-pcl (nuget). I need help on creating multiple tables. I have set up the requirements as below. I need to do the following:
1) I need to create tables and database when the App launches. How to do this in App.cs?
Update Problem:
1) Tables are not created. Why?
---1--- in PCL : add these
-- classes for table
using SQLite;
namespace MyApp.Model
{
[Table("TblCountry")]
public class Country
{
public string Country { get; set; }
public string CountryCode { get; set; }
public string OfficialLanguage { get; set; }
}
[Table("TblEmployees")]
public class Employee
{
[PrimaryKey, AutoIncrement]
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
}
--- interface class
using System;
using System.Collections.Generic;
using System.Text;
using SQLite;
namespace MyApp.DataAccessHelpers
{
public interface ISQLite
{
SQLiteConnection GetConnection();
}
}
---2---in Xamarin.Droid: I add this class
using SQLite;
using System.IO;
using Xamarin.Forms;
using MyApp.Droid.Implementation;
using MyApp.DataAccessHelpers;
[assembly: Xamarin.Forms.Dependency(typeof(AndroidSQLite))]
namespace MyApp.Droid.Implementation
{
class AndroidSQLite : ISQLite
{
public SQLite.SQLiteConnection GetConnection()
{
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
var path = Path.Combine(documentsPath, DatabaseHelper.DbFileName);
var conn = new SQLite.SQLiteConnection(path);
return conn;
}
}
}
------- Update :
public class DatabaseHelper
{
static SQLiteConnection sqliteconnection;
public const string DbFileName = "MyDb.db3";
public DatabaseHelper()
{
try
{
sqliteconnection = DependencyService.Get<ISQLite>().GetConnection();
sqliteconnection.CreateTable<CountryModel>();
sqliteconnection.CreateTable<EmployeeModel>();
}
catch (Exception ex)
{
string strErr = ex.ToString();
}
}
public List<CountryModel> GetAllCountry()
{
return (from data in sqliteconnection.Table<CountryModel>()
select data).ToList();
}
public CountryModel GetCountryByHuNbr(string name)
{
return sqliteconnection.Table<CountryModel>().FirstOrDefault(c => c.Name == name);
}
public void DeleteAllCountry()
{
sqliteconnection.DeleteAll<CountryModel>();
}
public void DeleteCountryByid(int ID)
{
sqliteconnection.Delete<CountryModel>(ID);
}
public void InsertCountry(CountryModel country)
{
sqliteconnection.Insert(country);
}
public void UpdateCountry(CountryModel country)
{
sqliteconnection.Update(country);
}
//------- CRUD for employee
public void InsertEmployee(EmployeeModel employee)
{
sqliteconnection.Insert(employee);
}
.....
... and all the CRUD for employee
}
}
Thanks in advance.
I created a helper class which contains all methods I need in order to interact with SQLite Database. I use the CreateTable() to create a table.
In App.xaml.cs file, I create an instance of my DataAccess helper class and I call the CreateLocalDbTables() method.
DataAccessHelper
public class DataAccess : IDisposable
{
private SQLiteConnection Connection;
#region Constructor
public DataAccess(ISQLitePlatform sQLitePlatform, string dbPath)
{
this.Connection = new SQLiteConnection(sQLitePlatform, dbPath);
}
#endregion
#region Methods
public void CreateLocaldbTables()
{
this.Connection.CreateTable<Registration>();
this.Connection.CreateTable<TransmissionLog>();
this.Connection.CreateTable<Parameters>();
this.Connection.CreateTable<Guest>();
}
In APP.xaml.cs
public partial class App : Application
{
#region Properties
public static DataAccess DBConnection { get; set; }
#endregion
public App(string localDbPath, ISQLitePlatform sqlitePlatform)
{
InitializeComponent();
DBConnection = new DataAccess(sqlitePlatform,localDbPath);
DBConnection.CreateLocaldbTables();
Model
namespace AppRegistration.Models
{
using SQLite;
using System;
[Table("Activity")]
public class Actividad
{
[Column("IdActivity")]
[PrimaryKey, Autoincrement]
public int IdActivity { get; set; }
[Column("IdEvent")]
[PrimaryKey]
public int IdEvent { get; set; }
[Column("ActivityDescription")]
[NotNull]
public string ActivityDescription { get; set; }
[Column("Status")]
[NotNull]
public string Status { get; set; }
[Column("UserId")]
[NotNull]
public int UserId { get; set; }
}
}

AspNet EF6 - Entity type has no key defined

So I changed up my databases and remade them. I followed the EF6 tutorial but encountered this error when trying to create a controller with views. I did some research on the error and people said to add data annotations and I tried [Key] but I keep getting the same error. Not sure if i've forgotten anything? Thanks!
"There was an error running the selected code generator: 'Unable to retrieve metadata for 'LinkDB.Models.Identifier.' Unable to determine the principal end of an association between the type 'LinkDB.Models.Identifier' and 'LinkDB.Models.Identity'. The principal end of this association must be explicity configured using either the relationship fluent API or data annotation.'
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace LinksDB.Models
{
public class Identity
{
[Key]
public int ID { get; set; }
public int IdentifierID { get; set; }
public string contact { get; set; }
public string contactname { get; set; }
public string price { get; set; }
public virtual ICollection<Link> Links { get; set; }
public virtual Identifier Identifiers { get; set; }
public virtual Metric Metrics { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace LinksDB.Models
{
public class Identifier
{
[Key]
public int ID { get; set; }
public string domain { get; set; }
public virtual ICollection<Link> Links { get; set; }
public virtual Identity Identitys { get; set; }
public virtual Metric Metrics { get; set; }
}
}
using LinksDB.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace LinksDB.DAL
{
public class LinkData : DbContext
{
public LinkData() : base("LinkData")
{
}
public DbSet<Identifier> Identifiers { get; set; }
public DbSet<Identity> Identitys { get; set; }
public DbSet<Link> Links { get; set; }
public DbSet<Metric> Metrics { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
OK, if you want a 1:1 relationship between Identity and Identifier those models should look like below where the child (Indentifier) uses the IdentityId as both it's PK and FK. You can also do this with fluent code. Start with this and then add in your Metric and Links relationships.
public class Identity
{
[Key]
public int ID { get; set; }
public string contact { get; set; }
public string contactname { get; set; }
public string price { get; set; }
public virtual Identifier Identifier { get; set; }
}
public class Identifier
{
[Key, ForeignKey("Identity")]
public int IdentityID { get; set; }
public string domain { get; set; }
public virtual Identity Identity { get; set; }
}
Example here

ASP.NET MVC 4 - Create a ViewModel from a base class (Model)

There is a class (Model) User.cs:
namespace BookStore
{
using System;
using System.Collections.Generic;
public class User
{
public int user_id { get; set; }
public string user_login_name { get; set; }
public string user_first_name { get; set; }
public string user_last_name { get; set; }
}
}
I want to create a ViewModel to then use it in Views. How should I do it? I create ViewModels folder in the project, create a class UserViewModel.cs in it, then what? I just copy and paste the original User.cs content and put limitations? Like this:
namespace BookStore.Models
{
public class UserViewModel
{
[Editable(false)]
public int user_id { get; private set; }
public string user_login_name { get; set; }
public string user_first_name { get; set; }
public string user_last_name { get; set; }
}
}
I did so and now my UserController says it can't implicitly convert type BookStore.User to BookStore.UserViewModel:
public class UserController : Controller
{
private DBEntities db = new DBEntities();
public ActionResult UserDetails()
{
UserViewModel user = db.Users.FirstOrDefault(u => u.user_login_name==User.Identity.Name);
if (user == null)
return RedirectToAction("Create");
else
return View(user);
}
I know it is important in MVC to separate concerns, domain models and view models should be used for different purposes, but why is there no any detailed info on how to create ViewModels correctly?

AutoMapper issue when try to map Model to ViewModel

I'm trying to map with AutoMapper
I have this model from data:
public partial class ModelFromData
{
public int Id { get; set; }
public int LastPosition { get; set; }
public virtual SomeModel SomeModel{ get; set; }
}
And my view Model
public class ViewModel
{
public int Id { get; set; }
public int LastPosition { get; set; }
public virtual SomeModel SomeModel{ get; set; }
}
My Mapper configures:
public class MapperConfig
{
public static void InitMaps()
{
Mapper.CreateMap<ModelFromData, ViewModel>();
Mapper.CreateMap<ViewModel, ModelFromData>();
Mapper.AssertConfigurationIsValid();
}
}
public static class MapExtensions
{
public static T To<T>(this Object from)
{
return Mapper.Map<T>(from);
}
}
When I try to AutoMap I get the folowing error:
Missing type map configuration or unsupported mapping.
Mapping types:
ModelFromData -> ViewModel
enter code here
Project.Data.ModelFromData -> Project.Web.Models.ViewModel
This is the error you will get when trying to map an object before the "CreateMap" is called. What framework are you using? I would hazard a guess at Asp.Net?
If so, Call your MapperConfig.InitMaps(); method from global.asax. Good answer here: https://stackoverflow.com/a/6825394/692830

Resources