Im trying to use EntityFramework with MySQL with .NET Framework and EF6 after long break.
I have very simple entity:
using System.ComponentModel.DataAnnotations.Schema; // for Index annotation
// ...
public class Bits
{
public long Id { get; set; }
// [Index] // adding index first try
public DateTime Datetime { get; set; }
public short B01 { get; set; }
public short B02 { get; set; }
}
And very simple DbContext:
public class MyContext : DbContext
{
public DbSet<Bits> Bits { get; set; }
public NbmsLoggerContext() : base()
{
Database.CreateIfNotExists();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Bits>().HasIndex(e => e.Datetime); // second try
}
}
I have tried to add annotation (see "first try" comment in code above).
I have tried to override OnModelCreating (see "second try" comment in code above).
After I delete database and Database.CreateIfNotExists(); recreates it I have no index on Datetime field. There is just an index on Id PK field.
I'm using MySQL.Data 8.0.28 because I couldn't manage to make 8.0.32 working .
Related
Trying to store a composite key table which is keyed for both fields to the table it defines dependencies for.
Example case
Import files: 1..10
Dependencies 1: 2,3; 2: 4,5; 4:10
Intent is to use this key-only table for code to do code first strongly typed definitions while also being light weight, and it seemed like the most straight forward way to do it before running into problems.
Current code:
public class ImportFileDependency
{
[Key]
[ForeignKey("ImportFile")]
public int ImportFileId { get; set; }
[ForeignKey("Id")]
public ImportFile ImportFile {get; set;}
[Key]
[ForeignKey("ImportFile")]
public int ImportFileDependencyId { get; set; }
[ForeignKey("Id")]
public ICollection<ImportFile> ImportFileDependencies { get; set; }
}
public class ImportFile
{
[Key]
public int Id {get; set;}
public string Name { get; set; }
public string WorkbookTab { get; set; }
public string File { get; set; }
public ICollection<ImportFileDependency> Dependencies { get; set; }
}
...
modelBuilder
.Entity<ImportFileDependency>(e =>{
e.HasKey(ifd => new { ifd.ImportFileId, ifd.ImportFileDependencyId });
e.HasOne(ifd => ifd.ImportFile)
.WithMany(i => i.Dependencies);
});
modelBuilder
.Entity<ImportFile>()
.HasMany(i => i.Dependencies)
.WithOne()
.HasForeignKey(z => z.ImportFileId);
...
After multiple revisions of following the responses of the add-migration exception response, currently on:
There are multiple properties pointing to navigation 'ImportFile' in entity type 'ImportFileDependency'. To define composite foreign key using data annotations, use ForeignKeyAttribute on navigation.
which did not update from the most recent iteration.
I seem to have recursed into a deadend so looking for guidance
Given the time you've asked it, you probably found the answer yourself or gave up on it, but if someone else struggles with this error, this solved my issue: Entity Framework Code First - two Foreign Keys from same table
You have to define the relationship using fluent API.
I'm using code first and I set up my enviernment and all was well. Problem is I'm comming back later and needed to add a new class (Foo) e.g.
public class NorthwindContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
...
public DbSet<Foo> Foos { get; set; } // added
}
public class Foo // added
{
public string FooID { get; set; }
public int Payload { get; set; }
}
public class Customer
{
...
However now whenever I try to update my service reference I get an error. If I take out the
public DbSet<Foo> Foos { get; set; }
All is well except there are no Foos in the generated code. What I'm I missing?
You have few options to resolve the problem. Remove the IncludeMetadataConvention included in your context. Then manually delete the database.
public class NorthwindContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Foo> Foos { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
base.OnModelCreating(modelBuilder);
}
}
or set the initializer in your programs entry point.
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<NorthwindContext>());
Final option would be to use Code First Migrations which is still in beta.
public class Purchase {
public Address to { get; set; }
public Address from { get; set; }
}
public class Address {
public string name { get; set; }
}
I have 1 Purchase with 2 Address. How this should be on the Database (mySql) including foreign keys to be used on Entity Framework.
I have the problem that entity understands (based on fk) that Navigability in Address is 1 to many (*) and I don't have a list of Address on Purchase, i have defined 2.
Thanks,
Bart.
You can configure relationships of the tables.Build your model like this,
public class PurchaseConfiguration : EntityTypeConfiguration<Purchase >
{
public PurchaseConfiguration()
{
HasRequired(p=>p.to ).WithOptionalDependent().WillCascadeOnDelete(false);
HasRequired(p => p.from ).WithOptionalDependent().WillCascadeOnDelete(false);
}
}
and your db context you can add the configurations like this,
public class yourDbContext:DbContext
{
public DbSet<Purchase> Purchases{ get; set; }
public DbSet<Address> Addresses{ get; set; }
//other db sets here..
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PurchaseConfiguration ());
// you can add configurations for other tables
}
}
I have a class Mailout with a Status that looks like this:
public class Mailout
{
public int Id {get; set; }
public string Name {get; set; }
public MailoutStatus Status { get; set; }
}
public class MailoutStatus
{
public int Id { get; set; }
public string Name { get; set;}
}
When I insert Mailouts and set the Status property, they are inserted correctly. When I fetch them, Status is always null. Since I don't have (and don't want) the status ID on my Mailout class, I have no way to retrieve it after-the-fact. How do I tell EF to populate this field eagerly, rather than lazily?
I'm hoping I can set something up in OnModelCreating() since I want this behavior all the time, not as an option that I can use sometimes by manipulating my LINQ-to-Entities queries.
You need to make your navigation properties virtual.
There is no such option in the ModelBuilder to configure an automatic eager loading of navigation properties in each query. You have to specify it query by query. As a workaround you could encapsulate eager loading in some method or property, for instance in the context:
public class MyContext : DbContext
{
public DbSet<Mailout> Mailouts { get; set; }
public IQueryable<Mailout> MailoutsWithStatus
{
get { return Mailouts.Include(m => m.Status); }
}
// ...
}
And then use in your queries:
context.MailoutsWithStatus.Where(...) ... etc.
Only an idea, it's untested.
Taking from Employee Info Starter Kit - upcoming MVC edition, here is a snippet, that works pretty well, to eager load objects when used:
public class Employee
{
...
public int? ReportsTo { get; set; }
[ForeignKey("ReportsTo")]
public virtual Employee Supervisor { get; set; }
/// <summary>
/// Children object collection of foreign key relation
/// </summary>
public virtual List<Employee> Subordinates { get; set; }
}
My question is similar to this one :
--> Many to one configuration using EF 4.1 code first
There are some fluent API solutions on google, with overriding "OnModelCreating" method and manually setting the foreign key options. But i would prefer a solution with data annotations if it is possible. Because I'd like to use inverse properties while coding. Such as TypeA object has got a TypeB object. So TypeB object should have a ParentTypeA property. Example :
public class User : IUser
{
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[RegularExpression(#"[A-Za-z0-9_\-\.]{2,32}"), MinLength(2), MaxLength(32)]
[Required(AllowEmptyStrings = false)]
public string UserName { get; set; }
// other props ....
// ....
public virtual UserGallery Gallery { get; set; }
}
public class UserGallery : IUserGallery
{
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserGalleryId { get; set; }
// other props ....
// ....
public virtual User ParentUser { get; set; }
}
A conventions way to do this in Code First is to use the UserID as the Primary Key of the UserGallery object. This is fine if its a true one to one relationship.
public class UserGallery : IUserGallery
{
[Key]
public int UserId {get;set;}
public User User {get;set;}
etc...
}
This has worked fine for me in the past.