I have an console application project in visual 2012. I want to use Entity Framework 6 code-first. when I run my project it does not create any database in my SQL Server. I am not able to create database by code first in my SQL Server.I am not getting any exception while build & run.
below is my code :
namespace CodeFirstNewDBeSample
{
class Program
{
static void Main(string[] args)
{
using (var db = new BlogContext())
{
//Console.Write("Enter a name for new Blog:");
//var name = Console.ReadLine();
//var blog = new Blog { Name = name };
//db.Blogs.Add(blog);
//db.SaveChanges();
}
}
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual IEnumerable<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
public class BlogContext : DbContext
{
public BlogContext() : base("name=BlogDBString") { }
DbSet<Blog> Blogs { get; set; }
DbSet<Post> Posts { get; set; }
}
}
Config File :
<connectionStrings>
<add name="BlogDBString" connectionString="data source=MY-PC;initial catalog=BlogDB;integrated security=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
Related
I'm implementing an ASP.NET Core 3.1 app. I have implemented following code to insert record in SQL Server database via EF Core but each time I save data, it inserts two records in PersonRequester and Requester table. I appreciate if anyone suggests me how I can prevent reinserting records.
Requester ap = new Requester();
ap.Address = RequesterViewModel.Requestervm.Address;
ap.RequesterType = RequesterViewModel.Requestervm.RequesterType;
ap.Description = RequesterViewModel.Requestervm.Description;
ap.Name = RequesterViewModel.Requestervm.Name;
var pa = new PersonRequester()
{
BirthCertificateNo = RequesterViewModel.personRequestervm.BirthCertificateNo,
IssuePlace = RequesterViewModel.personRequestervm.IssuePlace,
NationalCode = RequesterViewModel.personRequestervm.NationalCode,
Requester = ap
};
using (var context = new DBContext())
{
context.PersonRequester.Attach(pa);
try
{
context.SaveChanges();
}
catch (Exception e)
{
throw e;
}
}
public partial class Requester
{
public Requester()
{
PersonRequester = new HashSet<PersonRequester>();
}
public int RequesterId { get; set; }
public int RequesterType { get; set; }
public string Address { get; set; }
public string Description { get; set; }
public string Name { get; set; }
public virtual EntityType RequesterTypeNavigation { get; set; }
public virtual ICollection<PersonRequester> PersonRequester { get; set; }
}
public partial class PersonRequester
{
public int RequesterId { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public int RequesterType { get; set; }
public string NationalCode { get; set; }
public string BirthCertificateNo { get; set; }
public string IssuePlace { get; set; }
public virtual Requester Requester { get; set; }
public virtual EntityType RequesterTypeNavigation { get; set; }
}
I try to create the following database design with EF Core (code-first)
Entity "Recipe" can have a list of type "Resource"
Entity "Shop" can have a single "Resource"
Entity "InstructionStep" can have a list of type "Resource"
If I delete a resource from the "Recipe", "InstructionStep" (collections) or from the "Shop" (single-property) then the corresponding "Resource" entity should be also deleted. (Cascade Delete)
I already tried several things with and without mapping tables but none of my approach was successful.
Another idea was to have a property "ItemRefId" in the "Resource" entity to save the "RecipeId/ShopId/InstructionStepId" but I don't get it to work...
Example Classes:
public class Recipe
{
public int RecipeId { get; set; }
public string Title { get; set; }
public ICollection<RecipeResource> Resources { get; set; } = new List<RecipeResource>();
}
public class Shop
{
public int ShopId { get; set; }
public string Title { get; set; }
public Resource Logo { get; set; }
}
public class Resource
{
public int ResourceId { get; set; }
public string Path { get; set; }
public int ItemRefId { get; set; }
}
public class InstructionStep
{
public string InstructionStepId { get; set; }
public string Title { get; set; }
public ICollection<RecipeResource> Resources { get; set; } = new List<RecipeResource>();
}
Any suggestions? Many thanks in advance.
That's not cascade delete. Cascade delete would be when a Recipe is deleted, all of the related Resources are deleted as well.
In EF Core 3, you can use Owned Entity Types for this. The generated relational model is different from what you are proposing, in that Recipe_Resource and InstructionStep_Resource will be seperate tables, and Shop.Logo will be stored in columns on the Shop table. But that's the correct relational model. Having one Resource table with some rows referencing a Recipe and some rows referencing an InstructionStep is a bad idea.
This scenario is sometimes called a "Strong Relationship" where the identity of the related entity is dependent on the main entity, and should be implemented in the relational model by having the the Foreign Key columns be Primary Key columns on the dependent entity. That way there's no way remove a Recipe_Resource without deleting it.
eg
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
namespace EfCore3Test
{
public class Recipe
{
public int RecipeId { get; set; }
public string Title { get; set; }
public ICollection<Resource> Resources { get; } = new List<Resource>();
}
public class Shop
{
public int ShopId { get; set; }
public string Title { get; set; }
public Resource Logo { get; set; }
}
public class Resource
{
public int ResourceId { get; set; }
public string Path { get; set; }
public int ItemRefId { get; set; }
}
public class InstructionStep
{
public string InstructionStepId { get; set; }
public string Title { get; set; }
public ICollection<Resource> Resources { get; } = new List<Resource>();
}
public class Db : DbContext
{
public DbSet<Recipe> Recipes { get; set; }
public virtual DbSet<Shop> Shops { get; set; }
public virtual DbSet<InstructionStep> InstructionSteps { get; set; }
private static readonly ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddFilter((category, level) =>
category == DbLoggerCategory.Database.Command.Name
&& level == LogLevel.Information).AddConsole();
});
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseLoggerFactory(loggerFactory)
.UseSqlServer("Server=.;database=EfCore3Test;Integrated Security=true",
o => o.UseRelationalNulls());
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Shop>().OwnsOne(p => p.Logo);
modelBuilder.Entity<InstructionStep>().OwnsMany(p => p.Resources);
modelBuilder.Entity<Recipe>().OwnsMany(p => p.Resources);
}
}
class Program
{
static void Main(string[] args)
{
using var db = new Db();
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
var r = new Recipe();
r.Resources.Add(new Resource() { ItemRefId = 2, Path = "/" });
db.Recipes.Add(r);
db.SaveChanges();
r.Resources.Remove(r.Resources.First());
db.SaveChanges();
var s = new Shop();
s.Logo = new Resource { ItemRefId = 2, Path = "/" };
db.Shops.Add(s);
db.SaveChanges();
s.Logo = null;
db.SaveChanges();
}
}
}
Im having some issues trying to deploy a code first based mvc4 application to azure.
It works fine when creating a localdb however when trying to deploy to azure the UserProfile table only Username & UserId fields are created.
My model looks like
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public Guid ConsumerId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public bool IsMale { get; set; }
public string Mobile { get; set; }
[DefaultValue(false)]
public bool IsSmsVerified { get; set; }
public string SmsVerificationCode { get; set; }
}
Context
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<ExternalUserInformation> ExternalUsers { get; set; }
}
Configuration
internal sealed class Configuration : DbMigrationsConfiguration<Web.Models.UsersContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(Web.Models.UsersContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
Is there a magic switch somewhere that I need to turn on?
Here is my context:
public class ContentContext : DbContext
{
public ContentContext() : base("Name=CodeFirstDatabase") { }
public DbSet<Article> Articles;
public DbSet<ArticleTag> ArticleTags;
}
connection string:
<add name="CodeFirstDatabase" providerName="System.Data.SqlClient" connectionString="Server=X-ПК\SQLEXPRESS;Database=Products;Trusted_Connection=true;"/>
Global.asax:
Database.SetInitializer(new CreateDatabaseIfNotExists<ContentContext>());
HomeController:
public ActionResult Index()
{
ContentContext context = new ContentContext();
context.Database.Initialize(true);
Article a = new Article() { Text = "TEXT" };
context.Articles.Add(a);
context.SaveChanges();
return View();
}
Entities:
public class Article
{
public int Id { get; set; }
public string Author { get; set; }
public string Text { get; set; }
public virtual ICollection<ArticleTag> ArticleTags { get; set; }
}
public class ArticleTag
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Article Article { get; set; }
}
Database created as expected.But no tables created in it and I get null reference exception when I try add new Article. Any ideas? Thanks.
Change your DBSet<> in ContentContext to properties (instead of fields):
public DbSet<Article> Articles { get; set; }
public DbSet<ArticleTag> ArticleTags { get; set; }
I had to stop at the same stages following different MVC 4 code first technique tutorials, because database initialization failed.
Using the connection
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-DbTestApp-20130205173443;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-DbTestApp-20130205173443.mdf" providerName="System.Data.SqlClient" />
I can't even create or manage the database, which I want to be generated from my models
public class Category
{
public int Id { get; set; }
[Required]
[MinLength(4)]
[MaxLength(64)]
public string Name { get; set; }
public virtual IEnumerable<Article> Articles { get; set; }
}
public class Article
{
public int Id { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
[Required]
[MinLength(4)]
[MaxLength(64)]
public string Title { get; set; }
[Required]
[MinLength(16)]
[MaxLength(1024)]
[DataType(DataType.MultilineText)]
public string Content { get; set; }
[Required]
[Display(Name = "Post Anonymous?")]
public bool IsAnonymous { get; set; }
public int AuthorId { get; set; }
public virtual Author Author { get; set; }
public virtual IEnumerable<Comment> Comments { get; set; }
}
public class Author
{
public int Id { get; set; }
[MinLength(3)]
[MaxLength(64)]
public string AuthorName { get; set; }
public virtual IEnumerable<Article> Articles { get; set; }
public virtual IEnumerable<Category> Categories { get; set; }
}
public class Comment
{
public int Id { get; set; }
public int ArticleId { get; set; }
public virtual Article Article { get; set; }
[Required]
[MinLength(3)]
[MaxLength(64)]
public string Author { get; set; }
[MaxLength(64)]
public string Title { get; set; }
[Required]
[MinLength(4)]
[MaxLength(512)]
public string Content { get; set; }
}
using the context below
public class BlogContext : DbContext
{
public DbSet<Category> Categories { get; set; }
public DbSet<Article> Articles { get; set; }
public DbSet<Author> Authors { get; set; }
public DbSet<Comment> Comments { get; set; }
public BlogContext()
: base("DefaultConnection")
{
Configuration.ProxyCreationEnabled = false;
}
}
I also set the initializer in Global.asax Application_Start() method:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BlogContext>());
The problem comes when I'm trying to call
var articles = db.Articles.Include(a => a.Category).Include(a => a.Author);
inside my BlogController's Index() method to return a view with the list of stored articles. That happens every time calling a DB related methods, the error message is:
Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations.
In the tutorials I found nothing about problems like that and the solutions I read couldn't solve the problem.
Any ideas?
Thanks
DropCreateDatabaseIfModelChanges requires there to be a previous model already in place before it will compare the two. To start up the database you'll need to use the DropCreateDatabaseAlways initializer.