I have the model:
public class Movie
{
[Key]
public int MovieId { get; set; }
public string Title{ get; set; }
public ICollection<Actor> Actors { get; set; }
}
public class Actor
{
[Key]
public int AtorId { get; set; }
public string Nome { get; set; }
public ICollection<Movie> Movies { get; set; }
}
and the context:
public class MoviesContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
public DbSet<Actor> Actors { get; set; }
public MoviesContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MoviesContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Movie>().
HasMany(m => m.Actors).
WithMany(a => a.Movies).
Map(
m =>
{
m.MapLeftKey("MovieId");
m.MapRightKey("ActorId");
m.ToTable("ActorsMovies");
});
}
}
The table "ActorsMovies" is already created on sql server. how do I insert data into this table with entity framework? To insert data on the table Movies, for example, i've used the code db.Movies.Add(movie) and db.SaveChanges()
}
movie.Actors.Add(actor);
db.SaveChanges();
This should allow you to update the many to many table.
Related
I'm trying to make an insert in a SQL database using Entity Framework 6 and I'm stuck on this issue that I cannot solve.
The error that I keep getting is :
UpdateException: Entities in 'Connect.CompanyFinancialDetails' participate in the 'Company_CompanyFinancialDetails' relationship. 0 related 'Company_CompanyFinancialDetails_Source' were found. 1 'Company_CompanyFinancialDetails_Source' is expected
I have these 2 entities:
public class Company
{
public long CUI { get; set; }
public string UserName { get; set; }
public string CompanyName { get; set; }
public string Symbol { get; set; }
public int? SharesCount { get; set; }
public decimal? SharePrice { get; set; }
public virtual Account Account { get; set; }
public virtual CompanyFinancialDetails CompanyFinancialDetails { get; set; }
}
public class CompanyFinancialDetails
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
// other properties
public decimal? NumberOfEmployees { get; set; }
public virtual Company Company { get; set; }
}
This is the Fluent API configuration:
public DbSet<Account> SignUpModels { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<CompanyFinancialDetails> CompanyFinancialDetails { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Account>()
.HasKey(k => k.Id)
.HasOptional(s => s.Company)
.WithRequired(d => d.Account);
modelBuilder.Entity<Company>()
.HasKey(k => k.CUI)
.HasOptional(s => s.CompanyFinancialDetails)
.WithRequired(d => d.Company);
}
The relationship that I want to have is 1-many (one Company has many CompanyFinancialDetails).
This is the code where I add the objects to the database:
Company co = Context.Find(username);
foreach (CompanyFinancialDetails s in c)
{
s.Company = co;
}
a.CompanyFinancialDetails.AddRange(c);
a.SaveChanges();
I get a list of CompanyFinancialDetails and I add them using the AddRange method. I had this issue before and what I did was to add the virtual property object to the object that I wanted to insert in the database and it worked. This is what I tried to do here: the Find() method gets the company object that is related to the CompanyFinancialDetails and for each CompanyFinancialDetails object an Company virtual property is adding the related company object.
Well, it didn't work, when the SaveChanges() method is called, I get that error. Any help would be appreciated.
I have existing tables including the mapper table. I have to set the Entity Framework annotations. I am confused about how to achieve that. there are three tables,
Model (ModelId, ModelName),
Department (DepartmentId, DepartmentName)
ModelDepartmentMapper (ModelDepartmentMapperId, ModelId, DepartmentId, ModelStatus)
I have created the classes as:
public class Model
{
public int ModelId { get; private set; }
public string ModelName { get; private set; }
public virtual ICollection<Department> Departments { get; private set; }
}
public class Department
{
public int DepartmentId { get; private set; }
public string DepartmentName { get; private set; }
public virtual ICollection<Model> Models { get; private set; }
}
public class JoinModelDepartment
{
public int JoinModelDepartmentId { get; private set; }
public Guid ModelId { get; private set; }
public Guid DepartmentId { get; private set; }
public int ModelStatus { get; private set; }
}
And in DBContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Model>()
.HasMany<Department>(s => s.Departments)
.WithMany(c => c.Models)
.Map(cs =>
{
cs.MapLeftKey("ModelGuid");
cs.MapRightKey("DepartmentGuid");
cs.ToTable("JoinModelDepartment");
});
}
Please guide me how to add ModelStatus in the mapper table. Do I need to create it manually or there is a way to do this?
What I would tend to do is move these kinds of mappings into their own class files. Theres a brilliant tutorial found here:
https://www.entityframeworktutorial.net/code-first/move-configurations-to-seperate-class-in-code-first.aspx
This lets you map out each of the tables individually and it will build the database off of them.
So in your case you would have a Model, Department and a ModelDepartmentMapper class file. From there you can set all the relevant columns and how they are linked to another table as well as column types IE VARCHAR etc
I'm trying to have multiple tables with the same schema, within the same database, using Entity Framework.
For example, if I have the classes below, and I login to the SQL Server database, I can only see a table that is named something like dbo.Schema.
Is there a way to have multiple tables with the same schema?
class Context1 : DbContext
{
public DbSet<Schema> table1 { get; set; }
}
class Context2 : DbContext
{
public DbSet<Schema> table2 { get; set; }
}
class Schema
{
[Key]
public int EntryId { get; set; }
}
Is there a way to have multiple tables with the same schema?
You can either use Data Annotations or Fluent API to configure the table and schema name.
Suppose you have the following model:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Using Data Annotations, you could name it blogging.blogs:
[Table("blogs", Schema = "blogging")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Using Fluent API, you can override OnModelCreating method to name it blogging.blogs:
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable("blogs", schema: "blogging");
}
}
You can simple do like this with multiple tables.
public partial class AdventureWorksEntities : DbContext
{
public AdventureWorksEntities()
: base("name=AdventureWorksEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Address> Addresses { get; set; }
public virtual DbSet<AddressType> AddressTypes { get; set; }
public virtual DbSet<Contact> Contacts { get; set; }
public virtual DbSet<ContactType> ContactTypes { get; set; }
public virtual DbSet<CountryRegion> CountryRegions { get; set; }
public virtual DbSet<StateProvince> StateProvinces { get; set; }
}
in this code we can add more table from same database. There is no need to create another class and inherit DbContext.
or you can do Add Item into project-> New Item->Data->ADO.NET Entity Data Model.
This will generate same code with your selected tables.
Thanks
I have two tables one with a list of clients and the other whether they are active or not. I want to link them Entity Framework, however, I am struggling. The two tables were already setup and have to primary keys or foreign keys.
namespace DataWarehouse.Models
{
public class DatabaseList
{
[Key]
public string STARDB { get; set; }
public int DBClientID { get; set; }
public string ClientName { get; set; }
public DatabaseStatus DatabaseStatus { get; set; }
public ICollection<PayComponents> PayComponents { get; set; }
= new List<PayComponents>();
}
public class DatabaseStatus
{
[Key]
public string STARDB { get; set; }
public string STATUS { get; set; }
public DatabaseList DatabaseList { get; set; }
}
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options)
: base(options)
{
}
public DbSet<DatabaseList> DatabaseList { get; set; }
public DbSet<DatabaseStatus> Status { get; set; }
public DbSet<PayComponents> PayComponents { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DatabaseList>()
.HasOne(p => p.DatabaseStatus)
.WithOne(i => i.DatabaseList)
.HasForeignKey<DatabaseStatus>(k => k.STARDB);
}
}
}
I was hoping that Entity Framework would see the columns STARDB and notice that it is the same in both tables and match them that way. All I want to is to add the Status column from DatabaseStatus into the Databaselist table.
Thanks.
Managed to figure it out. My database was setup properly. However, I forgot the include statement in my Repository.cs class.
public IEnumerable<DatabaseList> GetAllClients()
{
_logger.LogInformation("Get all clients was called");
var clients = _ctx.DatabaseList
.Include(d => d.DatabaseStatus)
.OrderBy(p => p.ClientName)
.ToList();
return clients;
}
Still new to C# so a bit of learning curve!
I have problem because when I add the following to class Course I have only 2 tables not 3
public int PersonId { get; set; }
[ForeignKey("PersonId")]
public virtual Person Student { get; set; }
you do not have these three lines all good, but I need an additional field in class Course
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Course> CoursesAttending { get; set; }
}
public class Course
{
public int CourseId { get; set; }
public string Title { get; set; }
public int PersonId { get; set; }
[ForeignKey("PersonId")]
public virtual Person Student { get; set; }
public virtual ICollection<Person> Students { get; set; }
}
public class SchoolContext : DbContext
{
public DbSet<Course> Courses { get; set; }
public DbSet<Person> People { get; set; }
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer<SchoolContext>(
new DropCreateDatabaseAlways<SchoolContext>());
SchoolContext db = new SchoolContext();
var cos = from d in db.Courses
select d;
}
}
please help me
EF cannot decide if Course.Student or Course.Students refers to Person.CoursesAttending. You must give EF a hint, for example by using the [InverseProperty] attribute on Course.Students:
[InverseProperty("CoursesAttending")]
public virtual ICollection<Person> Students { get; set; }
Edit
The model will cause multiple cascading delete paths, namely: When you delete a Person records in the join table will be deleted as well, but it will also delete all Courses that this person is assigned to through the Course.Person property. The deleted Courses will delete records in the join table again which is the second delete path on the same table.
Multiple cascading delete paths are not allowed with SQL Server, so you must disable it with Fluent API:
public class MyContext : DbContext
{
//...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>()
.HasRequired(c => c.Student)
.WithMany()
.HasForeignKey(c => c.PersonId)
.WillCascadeOnDelete(false);
}
}