I have a problem to scaffolding my model.
I get following error "object reference not set to an instance of an object"
My model :
public class Position
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long PositionID { get; set; }
public long OfferID { get; set; }
[Required]
[Display(Name = "Positie omschrijving")]
public string Name { get; set; }
[Required]
public int PositionNr { get; set; }
[Required]
public double WorkingHeight { get; set; }
public long PalletTypeID { get; set; }
public long MotorTypeID { get; set; }
public long Enveriment { get; set; }
}
My DBContext :
public class FlowContext : DbContext
{
public DbSet<Position> Positions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
this.Configuration.LazyLoadingEnabled = true;
//Positie
modelBuilder.Entity<Position>()
.HasKey(j => j.PositionID);
}
}
My connection string in web.config
<connectionStrings>
<add name="FlowContext" connectionString="data source=.\SqlExpress; Integrated Security=True;Initial Catalog=Flow;" providerName="System.Data.SqlClient" />
Related
How do I map table value functions in Code with Entity Framework 6.3? I'm trying to a DB Context in code with an existing database, because EDMX is currently not supported in ASP.NET Core 3. I've tried setting up my DbContext clasee as below. I can successfully query the Grade table. But when I try to query my function "fn_GetCatgeories", I get the following error: No EdmType found for type 'WebApplication6.Data.ApplicationContext+fn_GetCategories'.
public class ApplicationContext : DbContext
{
public ApplicationContext(string cstr)
: base(cstr)
{
Database.SetInitializer<ApplicationContext>(null);
}
[Table("Grade")]
public class Grade
{
[Key]
public string Grade_ID { get; set; }
public string SchoolType { get; set; }
public int Sortorder { get; set; }
}
public partial class fn_GetCategories
{
public int Category_ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Nullable<bool> Active { get; set; }
public Nullable<System.DateTime> Month { get; set; }
public Nullable<int> Order { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new FunctionsConvention<ApplicationContext>("dbo"));
base.OnModelCreating(modelBuilder);
}
[DbFunction("ApplicationContext", "fn_GetCategories")]
public IQueryable<fn_GetCategories> GetCategories(Nullable<System.DateTime> month)
{
var monthParameter = month.HasValue ?
new ObjectParameter("Month", month) :
new ObjectParameter("Month", typeof(System.DateTime));
return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<fn_GetCategories>(string.Format("[0].{1}", GetType().Name, "[fn_GetCategories](#Month)"), monthParameter);
}
// DbSets here
public DbSet<Grade> Grades { get; set; }
}
This works:
public class ApplicationContext : DbContext
{
public ApplicationContext(string cstr)
: base(cstr)
{
Database.SetInitializer<ApplicationContext>(null);
}
[Table("Grade")]
public class Grade
{
[Key]
public string Grade_ID { get; set; }
public string SchoolType { get; set; }
public int Sortorder { get; set; }
}
public partial class fn_GetCategories_Result
{
[Key]
public int Category_ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Nullable<bool> Active { get; set; }
public Nullable<System.DateTime> Month { get; set; }
public Nullable<int> Order { get; set; }
}
// DbSets here
public DbSet<Grade> Grades { get; set; }
public DbSet<fn_GetCategories_Result> fn_GetCategoriesSet { get; set; }
public List<fn_GetCategories_Result> fn_GetCategories(DateTime month)
{
var m = new SqlParameter("Month", DateTime.Now);
return this.fn_GetCategoriesSet.SqlQuery("select * from dbo.fn_GetCategories(#month)", m).ToList();
}
I currently have a working WPF project that is using 2 tables from a sample Northwind database. Using Entity Framework code-first from an existing database these tables are displayed in master-detail format. I would like to use two views instead of the two tables.
I have found several tutorials and have implemented accordingly but for some reason I cannot get the dbcontext to read from the views. I created two views each matching the tables. I modified the class for the view to use [Table("vView")] and assigned a [Key] to create a primary key on the view but still no success. All research shows is to treat the view as if it was a table and all code should be the same. I am using Products and Categories table from Northwind database to test. I created their corresponding views vProducts and vCategories in the Northwind database.
Here is the code that works using the tables Products and Categories generated from the Entity Data Model (code-first):
Category.cs
namespace WPFCodeFirstExisting
{
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
public class Category
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Category()
{
Products = new HashSet<Product>();
}
public int CategoryID { get; set; }
[Required]
[StringLength(15)]
public string CategoryName { get; set; }
[Column(TypeName = "ntext")]
public string Description { get; set; }
[Column(TypeName = "image")]
public byte[] Picture { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Product> Products { get; set; }
}
}
Products.cs
namespace WPFCodeFirstExisting
{
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
public class Product
{
public int ProductID { get; set; }
[Required]
[StringLength(40)]
public string ProductName { get; set; }
public int? SupplierID { get; set; }
public int? CategoryID { get; set; }
[StringLength(20)]
public string QuantityPerUnit { get; set; }
[Column(TypeName = "money")]
public decimal? UnitPrice { get; set; }
public short? UnitsInStock { get; set; }
public short? UnitsOnOrder { get; set; }
public short? ReorderLevel { get; set; }
public bool Discontinued { get; set; }
public virtual Category Category { get; set; }
}
}
ProductContext.cs
namespace WPFCodeFirstExisting
{
using System.Data.Entity;
public partial class ProductContext : DbContext
{
public ProductContext()
: base("name=ProductContext")
{
Database.SetInitializer<ProductContext>(null);
}
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Product> Products { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(e => e.UnitPrice)
.HasPrecision(19, 4);
}
}
}
MainWindows.xaml.cs
public partial class MainWindow : Window
{
public ProductContext _context = new ProductContext();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
System.Windows.Data.CollectionViewSource categoriesViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("categoriesViewSource")));
_context.Categories.Where(x => x.CategoryName.Contains("P")).Load();
categoriesViewSource.Source = _context.Categories.Local;
}
App.config:
<connectionStrings>
<add name="ProductContext" connectionString="data source=ABC;initial catalog=Northwind;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
<add name="ProductContextView" connectionString="data source=ABC;initial catalog=Northwind;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
Now if I modify the code to use 2 views instead:
SELECT * FROM [dbo].[vProducts]
SELECT * from [dbo].[vCategories]
these views just contain the select statement from their respective tables.
vCategory.cs:
namespace WPFCodeFirstExisting
{
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("vCategories")]
public class vCategory
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public vCategory()
{
vProducts = new HashSet<vProduct>();
}
[Key]
public int CategoryID { get; set; }
[StringLength(15)]
public string CategoryName { get; set; }
[Column(TypeName = "ntext")]
public string Description { get; set; }
[Column(TypeName = "image")]
public byte[] Picture { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<vProduct> vProducts { get; set; }
}
}
vProducts.cs:
namespace WPFCodeFirstExisting
{
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("vProducts")]
public class vProduct
{
[Key]
public int ProductID { get; set; }
[Required]
[StringLength(40)]
public string ProductName { get; set; }
public int? SupplierID { get; set; }
[ForeignKey("CategoryID")]
public int? CategoryID { get; set; }
[StringLength(20)]
public string QuantityPerUnit { get; set; }
[Column(TypeName = "money")]
public decimal? UnitPrice { get; set; }
public short? UnitsInStock { get; set; }
public short? UnitsOnOrder { get; set; }
public short? ReorderLevel { get; set; }
public bool Discontinued { get; set; }
public virtual vCategory vCategory { get; set; }
}
}
ProductContextView.cs
namespace WPFCodeFirstExisting
{
using System.Data.Entity;
public class ProductContextView : DbContext
{
public ProductContextView()
: base("name=ProductContextView")
{
Database.SetInitializer<ProductContextView>(null);
}
public DbSet<vCategory> vCategories { get; set; }
public DbSet<vProduct> vProducts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<vProduct>()
.Property(e => e.UnitPrice)
.HasPrecision(19, 4);
}
}
}
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public ProductContextView _context = new ProductContextView();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
System.Windows.Data.CollectionViewSource categoriesViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("categoriesViewSource")));
_context.vCategories.Where(x => x.CategoryName.Contains("P")).Load();
categoriesViewSource.Source = _context.vCategories.Local;
}
When I run using the ProductContextView, These lines do not return any data;
_context.vCategories.Where(x => x.CategoryName.Contains("P")).Load();
categoriesViewSource.Source = _context.vCategories.Local;
I even tried doing something very simple like the following:
var prods = _context.Database.SqlQuery<vCategory>("Select * from dbo.vCategories");
foreach (var p in prods)
{
string test = p.CategoryName.ToString();
}
but prods doesn't return any data either. This test works perfectly fine when using the tables.
I'm hoping to just replace the tables with views using EF. I do not want to use any CRUD operations with the views they are fine being read-only.
What I found is that in code-first if you add a class representing a view as dbSet when the database is seeded it will create what you want to be a view as a table (probably why you are getting no results).
A work around is to create a custom an initializer :
public class CustomDBInitializer : CreateDatabaseIfNotExists<ProductContextView>
{
protected override void Seed(ProductContextView context)
{
base.Seed(context);
}
}
Then after the base seed method use...
context.Database.ExecuteSqlCommand()
...to drop the generated tables and run a SQL script that generates the views to replace them.
You can then use the dbset like a table but it will actually be using the view.
Also not sure why you created to separate contexts.
I am trying to ignore a class property when inserting data to database using metadata for the class but it is not working. I am using using EF 6. I have tried both the metadata and partial class are in the same assembly as the classes generated by EF
[NotMapped] and [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
Used a internal sealed class (for metadata) inside my partial class
namespace XeroDataStore.XeroDatabase
{
[MetadataType(typeof(TempAddressMetadata))]
public partial class TempAddress
{
}
[MetadataType(typeof(TempContact.TempContactMetadata))]
public partial class TempContact
{
internal sealed class TempContactMetadata
{
[NotMapped]
public Nullable<System.DateTime> UploadDate { get; set; }
}
}
}
namespace XeroDataStore.XeroDatabase
{
public class TempAddressMetadata
{
[NotMapped]
public Nullable<System.DateTime> UploadDate { get; set; }
}
}
EF Generated Class
namespace XeroDataStore.XeroDatabase
{
public partial class TempAddress
{
public int RowId { get; set; }
public int ClientID { get; set; }
public System.Guid ContactID { get; set; }
public string AddressType { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressLine4 { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string AttentionTo { get; set; }
public Nullable<System.DateTime> UploadDate { get; set; }
public virtual TempContact TempContact { get; set; }
}
}
What am I missing here?
Do it using Fluent API to make sure your model classes are POCO and have nothing to do with the data access.
In your data context, OnModelCreating methoed, use the following code to ignore the property
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TempContact>().Ignore(a => a.UploadDate );
}
public class project
{
public int id { get; set; }
public string ProjectName { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public int UserprojectId { get; set; }
public int? SponserId { get; set; }
public decimal Cost { get; set; }
public DateTime CreatedTime { get; set; }
public DateTime EstimateTime { get; set; }
}
public class projectDB : DbContext
{
public DbSet<project> projects { get; set; }
}
and this model
public class sponser
{
public int id { get; set; }
public string FirstName { get; set; }
public string lastName { get; set; }
public string CompanyName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public DateTime DateRegister { get; set; }
public String CompanyPhone { get; set; }
public string CellPhone { get; set; }
public string Email { get; set; }
public bool EmailConfirmation { get; set; }
public string Country { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public String Address { get; set; }
}
public class sponserDB : DbContext
{
public DbSet<sponser> sponsers { get; set; }
}
and in my web confige file
i add this this name
<add name="SponseringDB"
connectionString="Data Source=(localdb)\v11.0;Initial Catalog=sponseringDB;Integrated Security=True"
providerName="System.Data.SqlServerCe.4.0"
/>
When run this and create some Record for me it made two database first sponseringDb and second is projectDb I want to use one database.
Need suggestions on achieving this.
You've got two classes inherit by DbContext and that is the reason why 2 database are created, if you want to have just one databe ie: projectDB
change you projectDB class to
public class projectDB : DbContext
{
public projectDB () : base("projectDBConnectionString") //<- name of your connection string
{
}
public DbSet<project> projects { get; set; }
public DbSet<sponser> sponsers { get; set; }
}
and in your web config add connection string named 'projectDBConnectionString' ie:
<add name="projectDBConnectionString"
connectionString="Data Source=(localdb)\v11.0;Initial Catalog=sponseringDB;Integrated Security=True"
providerName="System.Data.SqlServerCe.4.0"
/>
and now your can rid off connection string 'SponseringDB' from web.config and delete class 'sponserDB'
Hope that will help
I'm building an mvc application and using code first. But when I'm try access the table, the mvc throw this error:
Invalid object name 'dbo.Membro'.
My Context is:
public class JethroContext : DbContext
{
public DbSet<Area> Areas { get; set; }
public DbSet<BaseIgreja> BaseIgrejas { get; set; }
public DbSet<Igreja> Igrejas { get; set; }
public DbSet<Celula> Celulas { get; set; }
public DbSet<Membro> Membros { get; set; }
public DbSet<Distrito> Distritos { get; set; }
public DbSet<Setor> Setores { get; set; }
public DbSet<Usuario> Usuarios { get; set; }
public DbSet<Ministerio> Ministerios { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
Searching on Google I found the solution, but not worked for me.
Database.SetInitializer<JethroContext>(null);
EDIT I:
Membro class
Public class Membro
{
public int Id {get;set;}
public String Name {get;set;}
public DateTime DateCreate {get;set;}
}
Invalid object name 'dbo...'.
I just realised I had the wrong Catalog selected in my Connection string. Master Blunder!!!