I found the problem, Solution is at comments.
I can create tables and diagram but I can not seed data to table.
1.I installed EF by Nuget.
2.From PM console I wrote Enable-Migrations –EnableAutomaticMigrations.
Model is in All.Model class library and and context methods are in All.Dal class library I did not understand what am I doing wrong can you help me?
This is my context code:
using All.Model;
namespace All.Dal
{
public class AllDb : DbContext
{
public AllDb()
{
Database.Connection.ConnectionString = "Server=SEUPHORIA;Database=AllDb;UID=sa;PWD=123;";
}
public DbSet<Category> Categories { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Line> Lines { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<AllDb>(new DbStrategy());
modelBuilder.Entity<Category>().Property(c => c.Name).IsRequired();
modelBuilder.Entity<Comment>().Property(c => c.Letter).IsRequired();
}
}
}
And this is my strategy code:
using All.Model;
namespace All.Dal
{
public class DbStrategy : DropCreateDatabaseIfModelChanges<AllDb>
{
protected override void Seed(AllDb context)
{
List<Category> CategoryDefault = new List<Category>
{
new Category { Name="Organic", UpID = 0 },
new Category { Name="Object", UpID=0},
new Category { Name="Time",UpID=0},
};
foreach (Category item in CategoryDefault)
{
context.Categories.Add(item);
} context.Users.Add(new User { Name = "sss" });
}
}
}
this is my category class:
public class Category : Standart
{
public int UpID { get; set; }
public string Name { get; set; }
public int LineID { get; set; }
public virtual List<Line> Lines { get; set; }
}
You are adding the items into the DB context but are not committing the changes by calling SaveChanges() on them. Just add this one line:
protected override void Seed(AllDb context)
{
List<Category> CategoryDefault = new List<Category>
{
new Category { Name="Organic", UpID = 0 },
new Category { Name="Object", UpID=0},
new Category { Name="Time",UpID=0},
};
foreach (Category item in CategoryDefault)
{
context.Categories.Add(item);
}
context.Users.Add(new User { Name = "sss" });
context.SaveChanges(); // make sure you save!
}
Related
I'm new to EF (table first) and I don't know why these related entities are not saving at all to my database.
These are the related entities, UserProfile has a set of Carts
public partial class UserProfile
{
public UserProfile()
{
Cart = new HashSet<Cart>();
Naquestions = new HashSet<Naquestions>();
}
public int Id { get; set; }
public string BotUserId { get; set; }
public int? PrestashopId { get; set; }
public bool Validated { get; set; }
public int Permission { get; set; }
public DateTime CreationDate { get; set; }
public ICollection<Cart> Cart { get; set; }
public ICollection<Naquestions> Naquestions { get; set; }
}
Cart has a set of OrderLines
public partial class Cart
{
public Cart()
{
OrderLine = new HashSet<OrderLine>();
OrderRequest = new HashSet<OrderRequest>();
}
public int Id { get; set; }
public int UserId { get; set; }
public bool Active { get; set; }
public UserProfile User { get; set; }
public ICollection<OrderLine> OrderLine { get; set; }
public ICollection<OrderRequest> OrderRequest { get; set; }
}
And when I try to add them:
public async Task AddOrderLineToUser(string botId, OrderLine orderLine)
{
using (var context = ServiceProvider.CreateScope())
{
var db = context.ServiceProvider.GetRequiredService<GretaDBContext>();
var user = await UserController.GetUserByBotIdAsync(botId);
var latestCart = user.Cart.OrderByDescending(c => c.Id).FirstOrDefault();
if (latestCart != null && latestCart.Active)
{
latestCart.OrderLine.Add(orderLine);
}
else
{
var newCart = new Cart()
{
Active = true,
};
newCart.OrderLine.Add(orderLine);
user.Cart.Add(newCart);
}
await db.SaveChangesAsync();
}
}
Nothing is saving to the database once db.SaveChangesAsync() is called.
As #Caius Jard said in the comments it seems that user comes from another context. Try
if (latestCart != null && latestCart.Active)
{
orderLine.CartId = latestCart.Id;
db.OrderLines // I assume it is name of your orderlines DbSet
.Add(orderLine);
}
else
{
var newCart = new Cart()
{
Active = true,
UserId = user.Id,
};
newCart.OrderLine.Add(orderLine);
db.Carts // also assuming name of DbSet
.Add(newCart);
}
Also you can take a look at Attach method.
But I would say that in general you are doing something not good. Usually creating new scope is not needed, and db context should be injected in corresponding class via ctor. If you still need to create new scope it would make sense to resolve UserController also. Also is UserController an ASP controller?
I have a model with one entity:
namespace TestMigration
{
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public int FollowersCount { get; set; }
//public int BloggerAge { get; set; }
}
}
The Initializer class:
public class DataInitializer : DropCreateDatabaseAlways<BlogContext>
{
protected override void Seed(BlogContext context)
{
var blogs = new List<Blog>
{
new Blog {FollowersCount=456, Name="ABC", Url="abc.com" },
new Blog {FollowersCount=789, Name="DEF", Url="def.com" },
new Blog {FollowersCount=246, Name="GHI", Url="ghi.com" },
new Blog {FollowersCount=135, Name="JKL", Url="jkl.com" },
new Blog {FollowersCount=258, Name="MNO", Url="mno.com" }
};
blogs.ForEach(b => context.Blogs.Add(b));
context.SaveChanges();
}
}
Main Method:
static void Main(string[] args)
{
Database.SetInitializer(new DataInitializer());
using (var db = new BlogContext())
{
//db.Blogs.Add(new Blog { Name = "KOLP" });
//db.SaveChanges();
foreach (var blog in db.Blogs)
{
Console.WriteLine($"\n*****({blog.BlogId})*****");
Console.WriteLine("blog.Name: " + blog.Name);
}
}
Console.ReadLine();
}
To understand the role of DropCreateDatabaseAlways I deleted a property from this entity(Blog), and when I run the application, it throws this error:
There is already an object named 'Blogs' in the database.
Shouldn't it drop the database at any case, and then recreate it from the presented model?
I have a situation where the code I've arrived at doesn't match any examples I find so I wonder if I'm missing something.
Basically, I want an EF code first Entity that contains a collection of Entities participating in a many-to-many relationship.
Then, I'd like to be able to:
Add to collection at the same time as creating an entity
Not get a warning about accessing a virtual member from constructor
Here's what I have:
public class NotificationUser
{
private ICollection<NotificationUserGroup> _userGroups = new HashSet<NotificationUserGroup>();
public int UserId { get; set; }
public string UserName { get; set; }
public bool IsActive { get; set; }
public virtual ICollection<NotificationUserGroup> UserGroups
{
get { return _userGroups; }
set { _userGroups = value; }
}
}
Is there a better/different way to accomplish my goal?
This example might help
public class NotificationUser
{
public NotificationUser()
{
UserGroups = new HashSet<NotificationUserGroup>();
}
public int NotificationUserId { get; set; }
public string UserName { get; set; }
public bool IsActive { get; set; }
public virtual ICollection<NotificationUserGroup> UserGroups { get; set; }
}
public class NotificationUserGroup
{
public int NotificationUserGroupId { get; set; }
public string GroupName { get; set; }
}
public class Context : DbContext
{
public Context()
: base()
{
}
public DbSet<NotificationUser> NotificationUsers { get; set; }
public DbSet<NotificationUserGroup> NotificationUserGroup { get; set; }
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
using (var ctx = new Context())
{
var user = new NotificationUser() { UserName = "Name1" };
user.UserGroups.Add(new NotificationUserGroup() { GroupName = "Group1" });
user.UserGroups.Add(new NotificationUserGroup() { GroupName = "Group2" });
ctx.NotificationUsers.Add(user);
ctx.SaveChanges();
}
using (var ctx = new Context())
{
foreach (var user in ctx.NotificationUsers)
{
foreach (var group in user.UserGroups)
Console.WriteLine("Group Id: {0}, Group Name: {1}, UserName: {2}", group.NotificationUserGroupId, group.GroupName,user.UserName);
}
foreach (var group in ctx.NotificationUserGroup)
{
Console.WriteLine("Group Id: {0}, Group Name: {1}", group.NotificationUserGroupId, group.GroupName);
}
}
Console.ReadKey();
}
}
I am new to WPF and have a beginner question. Whenever I added data to a collection my UI was only getting updated after I restarted the program. I was originally using ICollection but realized I need to use OvservableCollection to update the collection. When I swtiched the Customers property from ICollection to ObservableCollection I get an error on my UpDate method saying I can't implicitly convert. Is possible to cast an ObservableCollection. How else could I fix this issue? Thanks in advance.
ViewModel.cs
public ViewModel()
{
Customers = new ObservableCollection<Customer>();
UpDate();
}
public void UpDate()
{
Customers.Clear();
foreach (var customer in context.Customers.OrderBy(c => c.Name))
{
Customers.Add(customer);
}
}
#region Add new customer,project,program,rev methods
public void AddCustomer(string customerName)
{
using (context = new RevisionModelContainer())
{
var customer = context.Customers;
customer.Add(new Customer { Name = customerName });
context.SaveChanges();
UpDate();
}
}
public ObservableCollection<Customer> Customers { get; set; }
public ObservableCollection<Project> Projects { get; set; }
public ObservableCollection<Program> Programs { get; set; }
public ObservableCollection<Revision> Revisions { get; set; }
public DateTime Dates { get; set; }
public string Notes { get; set; }
Customer.cs
public partial class Customer
{
public Customer()
{
this.Projects = new ObservableCollection<Project>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ObservableCollection<Project> Projects { get; set; }
}
create instance of Customers in ViewModel constructor
public ViewModel()
{
Customers = new ObservableCollection<Customer>();
UpDate();
}
and populate the list when UpDate is called
public void UpDate()
{
Customers.Clear();
foreach(var customer in context.Customers.OrderBy(c => c.Name)) Customers.Add(customer);
}
I am developing a MVC Project with Entity framework and i have a category table like this :
public partial class Categories
{
public Categories()
{
this.Categories1 = new HashSet<Categories>();
}
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public Nullable<int> RelatedCategoryId { get; set; }
public virtual ICollection<Categories> Categories1 { get; set; } //Children
public virtual Categories Categories2 { get; set; } //Parent
}
When i get table data with EF, it gives me the object i want. Parents with children.
class Program
{
static Entities db = new Entities();
static void Main(string[] args)
{
List<Categories> categories = db.Categories.Where(item => item.RelatedId == null).ToList();
}
}
With relatedId == null part, i get the main categories which has no parent.
There is no problem this far. But i want to cast categories object which ef returned to another class which is :
public class NewCategories
{
public int Id { get; set; }
public string Name { get; set; }
private List<NewCategories> _subCategories;
public NewCategories()
{
_subCategories= new List<NewCategories>();
}
public List<NewCategories> SubCategories { get { return _subCategories; } }
}
And i want new List<NewCategories> newCategories object.
How can i accomplish that?
Thanks.
I think you have to create a recursive method to convert Categories to NewCategories, something like this (I'm not sure if it works, but it's worth trying):
public NewCategories ConvertToNewCategories(Categories cat){
NewCategories nc = new NewCategories {Id = cat.CategoryId, Name = cat.CategoryName};
nc.SubCategories.AddRange(cat.Categories1.Select(c=>ConvertToNewCategories(c)));
return nc;
}
//Then
List<NewCategories> categories = db.Categories.Where(item => item.RelatedId == null)
.Select(item=>ConvertToNewCategories(item))
.ToList();