MVC - Using Custom Class for Model Property - c#

I would like to preface this by saying, I am a web developer that started in C++ before learning ASP.NET C#.
So I have a Model in my web app that has a property that I would like use a custom class as the datatype of the property. I am not sure where to store the custom class in the folder structure in Visual Studio. Also, I am not sure I am setting this up correctly.
Custom Class
public class ClassName
{
public int value1;
public int value2;
}
public ClassName(int v1)
{
value1 = v1;
value2 = v2
}
Model
public class Model
{
public int ID { get; set; }
public string Name { get; set; }
public List<ClassName> ClassNames {get; set;}
}
I do not want the custom class on the database. I have been doing Code First with Migrations in Visual Studio and keeps trying to push the custom class into the database. Any ideas on what I could have setup wrong or what I need to do to get what I am looking for.

As far as folder structure -
Look into the Model View Controller pattern for Asp.Net, very nice pattern. Store your models in a folder called 'models', controllers under 'controllers' Views under 'views' etc.
as far as using 'classname' in your table, im not too sure if you can use classes for rows. not sure how the database table would accomdate that.
Perhaps you need to create another table for classname, and then reference those records back to your first table using a foreign key?

If you don't want the public class Model in the database then do an add-migration IgnoreChanges using the VS Package Manager Console.
This will create the migration class called IgnoreChanges and then in the public override void Up() and public override void Down() functions just delete any code you dont want.
like this:
public partial class IgnoreChanges : DbMigration
{
public override void Up()
{
// No code here
}
public override void Down()
{
// No code here
}
}
Perform an update-database and volia... no changes are added to the database.
You are basically fooling Migrations into thinking it has run your model into the database.
Migrations takes a snapshot of your database at the time you perform an add-migration so by removing the code you don't want published to the database, migrations will still recognise that your change has been generated, even though you removed the code from the public override void Up() and public override void Down() functions
Hope this makes sense

Related

Consuming View in EF Code First conflicts with migration

I have a Table "IncomingChecks" in my database. I've created it using EF Code first. Now, I've added a view to my database based on this table named "ViewIncomingChecks" using Sql Server Management Studio and I want to use its data in my app using Entity Framework.
I copied the model class and changed its name and added it to the context:
public class ViewIncomingCheck
{
[Key]
public int Id { get; set; }
//...
}
public class CheckDataContext : DbContext
{
public virtual DbSet<ViewIncomingCheck> ViewIncomingChecks { get; set; }
//...
}
now when I run the app, it throws an exception saying the DB Context has been changed and needs a migration. I even tried to add a migration (which seems to be the wrong option) and when I add the migration, it says that the object ViewIncomingChecks is already in the database.
How can I use this view in my code?
Edit
My current solution is to have another context just for the views. This way it doesn't conflict with the EF Migrations. Is this the best option or is there a better way to deal with it.
According to what I have done in my project:
First add public virtual DbSet<ViewIncomingCheck> ViewIncomingChecks
{ get; set; } to your DbConext
Now create a migration something called ViewDbSetAdded
Remove all the code from the both Up and Down method and it will look like as follows:
Migration Code:
public partial class ViewDbSetAdded : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
Now run update-database command and it will run an empty migration.

How to know project is code-first or database-first?

In an existing project, how do I know if it's code-first or database-first?
Project has this lines of code:
public class TestDBContext : DbContext
{
public DbSet<Player> Players { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
And project has no .edmx file. If any other details need I will share.
EDIT:
Player.cs class
public class Player
{
public int PlayerID { get; set; }
public string PlayerName { get; set; }
}
EDIT 12.05.2017
IF I change database name from connection string and run project, it creates database with the new name with all tables. May be this will be hit for the answer.
If this is a project is Database-first, there is :
[name].edmx diagram file and with it, [name].Context.tt & .cs
every tables that are translated into class are hidden in tree like .edmx > .tt
in OnModelCreating, there is a throw new UnintentionalCodeFirstException()
If not, all the class issue from the tables are in the project (no tree).
Here I am sharing my observation.
Mainly there are two approaches to implement Entity Framework.
1. Code-first
If chosen, it will create simple .cs file(s) which developers later modifies as per their requirement.
Data-first
If chosen, it will create a [name].edmx file along with hierarchy of different files. It contains .Context.tt and underneath .Context.cs file.
The .Context.cs file will have below snippet which indicates whether induced entity model was empty when created or it was with any database object.
namespace Search
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class XYZ_MSCRMEntities : DbContext
{
public XYZ_MSCRMEntities()
: base("name=xyz_MSCRMEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<AnyDatabaseTableOrView> TableOrViewPluralized { get; set; }
}}
In above snippet, very last line (DbSet property) shows that it has imported database object and that is how it is "Data-first"
If there is no .edmx file, the project is code-first.

Can't query value from newly created column

I just added a new column to the database for a project. I confirmed that the column exists the database. I've added the property to my model and my dbset is defined using that model. However, as soon as I try to query that column value, it gives me NotSupportedException.
The specified type member 'screen_icon' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
Context class
public partial class dml_entities : DbContext
{
public dml_entities() : base("name=dml_entities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
// ...
public virtual DbSet<screen> screen { get; set; }
// ...
}
Model
public partial class screen
{
// ...
public string screen_icon { get; set; }
// ...
}
Controller code
public class ScreenController : ApiController
{
private dml_entities db = new dml_entities()
public IQueryable<object> Get_screen()
{
return db.screen.Select(e => new { icon = e.screen_icon });
}
}
Edit:
When I db.screen.ToList() before selecting from it, the error goes away, but 'screen_icon' is always null, even if there actually is a value in the db.
For whatever reason, it seems like my code doesn't believe that the column exists in the database.
Edit2:
Not sure if its relevant, but the exception does not seem to trigger in the controller code itself. Attempting to try{} catch{} creates the same result.
Does screen_icon has getter and setter or it is a variable? Should be a property
What is the name and type in database? Maybe try forcing column name with attrbiute like:
[Column("screen_icon")]
public string screen_icon { get; set; }
It turns out that the project was using an edmx file to manage their models. Due to the amount of noise in the file I edited and the fact that I found it through "go to definition" and the not the file explorer, I didn't realize that the model file was generated from the Entities.edmx file.
Once I updated the model in from the edmx designer, my code worked as expected. And I learned that its important to keep an eye out for comments that inform you not to edit it manually because its an auto-generated file.
Try:
return db.screen.ToList().Select(e => new { icon = e.screen_icon });

Set up database creation/migrations from code for Entity Framework 6 + MySQL

I've previously used NHibernate and Fluent Migrator in projects to create a database (if it didn't already exist) and update the schema through migration scripts. I'm looking over Entity Framework (6) to do a comparison and I'm having trouble replicating that functionality.
In my App.config, I've set up my connection string and db providers. I then went ahead and created a data model that I would like to be represented as a table in the database.
namespace DataModels
{
public class StoreClient
{
public int Id;
public string DisplayName;
public StoreClient()
{
}
}
}
I then went ahead and created a database context.
namespace DataModels
{
public class StoreContext : DbContext
{
public DbSet<StoreClient> StoreClients { get; set; }
}
}
On service start I created an instance of StoreContext and tried to add and call db.SaveChanges();, but this is failing because there is no schema that matches my StoreClient.
My question is simple. How do I configure my StoreContext (or EF in general) to automatically create my database schema, and how do I set it up to migrate when I make changes to that schema?
This seems simple, but my searching around hasn't gotten me anything that looks remotely familiar coming from the NHibernate world.
If you want your db to be created automatically try to put some code in your Application_Start() method.
for example:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<StoreContext, Configuration>());
StoreContext context = new StoreContext();
context.Database.Initialize(true);
Where Configuration class is created upon automatic migrations are enables in the console. Check out this msdn demo.
Also i am not shure that your code firs model will work that way. If not try changing your fields with properties.
namespace DataModels
{
public class StoreClient
{
public int Id { get; set; }
public string DisplayName { get; set; }
public StoreClient()
{
}
}
}

DataSet ToList method returns empty List, even though it has elements

Sorry if somebody has already asked this question. I've been looking around but couldn't find anything related.
So, I am using Entity Framework and I am trying to load the list of "Idiomas" from the dataset using the ToList method through the following code:
//List<Idioma> ans = new List<Idioma>(contexto.Idiomas);
return contexto.Idiomas.ToList();
However, the method is returning an empty list, even though I can see through the debugger that the DataSet has elements.
EDIT
I have not put any extra code because there is not any extra code besides those two lines.
I just create a Entity Framework model-first, generated the database, and updated the model from the database to make sure everything was ok.
Contexto is a instance from the class LivroContexto, which implements DbContext (auto generated by vs2012, see below).
LivroContainer:
public partial class LivroContainer : DbContext
{
public LivroContainer() : base("name=LivroContainer")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
public DbSet<Idioma> Idiomas { get; set; }
}
Idiomas:
public partial class Idioma
{
public Idioma()
{
this.Traducaos = new HashSet<Traducao>();
}
public int IdIdioma { get; set; }
public string Lingua { get; set; }
public virtual ICollection<Traducao> Traducaos { get; set; }
}
Thank you
nobody can see, why your code is not working, from the amount of code you have posted.
however, make sure following :
the class of the instance contexto inherits DbContext or any child class inheriting DbContext.
make sure, in case, you have not generated the database, through the code,rather mapped an existing database, to a codefirst frontend, that DbSet<Idioma> Idiomas is mapped to proper table. ie.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Idioma>().ToTable("IdiomaTableNameInDatabase");
}
make sure, your connectionString name, that you passed in the DbContext base constructor is present in the web.config, and if you have not passed anything, make sure a connectionString with the name of your DbContext inheriting class is there.
If all these are correct, there is absolutely no reason, why contexto.Idiomas.ToList() won't return anything.
and also, say, your context class is MyContext, then it should be like this:
public class MyContext:DbContext
{
public MyContext:base("ConnectionStringName")
{
}
//--dbSet properties
public DbSet<Idioma> Idiomas{get;set;}
//other overridden methods
}
which you use, on your upper layers like this:
public List<Idioma> GetAllIdiomas()
{
MyContext contexto = new MyContext();
return contexto.Idiomas.ToList();
}

Categories