Develop Entity Framework class that will define a .mdf database - entity-framework

I am trying to develop Entity Framework class that will define a .mdf database already created and filled leading up to actually creating one and filling it.
Error:
One or more validation errors were detected during model generation:
testclass.test: : EntityType 'test' has no key defined. Define the key for this EntityType.
testData: EntityType: EntitySet 'testData' is based on type 'test' that has no keys defined.
Code:
using System.Data.Entity;
namespace testclass
{
public class test
{
public int idt { get; set; }
public string datetime { get; set; }
public string col1 { get; set; }
public string col2 { get; set; }
public string col3 { get; set; }
}
public class TestDbContext : DbContext
{
public DbSet<test> testData { get; set; }
}
public class testRepository
{
public List<test> Gettest()
{
TestDbContext testDbContext = new TestDbContext();
return testDbContext.testData.ToList();
}
}
}
connection string:
<connectionStrings>
<add name="TestDbContext" connectionString="Data Source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=C:\folders\testclass\testclass\App_Data\Data.mdf;User Instance=true;" providerName="System.Data.SqlClient" />
</connectionStrings>

There is some issues with your code:
the main is the lack of a primary key on your entity: EF can infer some keys if their names match some conventions : "Id", "ID", "testId"... So either use one of these standard names or explicitly mark your property as a primary key with the [Key] attribute:
[Key]
public int idt { get; set; }
to ensure proper cleanup of the resources allocated by the DbContext you should wrap its usage in a using block:
using (TestDbContext testDbContext = new TestDbContext())
{
return testDbContext.testData.ToList();
}
in .Net the naming conventions are: CamelCase for everything except local variables and fields; so testclass should be Testclass, col1 should be Col1, testData should be TestData...

Related

The entity type required a primary key to be defined - but there is

I probably have a fairly trivial problem with EF configuring 1 table. This is how my class looks like:
public class Task
{
[Key]
public int Id { get; set; }
[Required]
public string Description { get; set; }
[Display(Name = "Modification Date")]
public DateTime ModificationDate { get; set; }
[Required]
public bool IsDone { get; set; }
}
This is how dbContext looks like:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions options) : base (options) { }
public DbSet<Task> Tasks { get; set; }
}
And while creating migration I get this error:
The entity type 'Task' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating' [...]
But as you can see I have an attribute [Key], the property is public and has a setter, what could be the problem?
Ok, that was the dumbest mistake in a long time. It turned out the context was using the Task system class instead of my model class...

Using OData with model inheritance cause missing property error

I got this error in my OData with asp.net core implementation during the runtime :The EDM instance of type '[XXX.Asset Nullable=True]' is missing the property 'externalId'.
The problem appear when I try to access the odata endpoint with the expand query: "/odata/v1/precinct?$expand=assets". It seems happening because I put the "ExternalId" property in my base class, its not happening if I put that property in the "Asset".
Below is my recent codes:
public abstract class Entity
{
public int Id { get; set; }
public string ExternalId { get; set; }
}
public class Precinct : Entity
{
public string Name { get; set; }
public string Description { get; set; }
public virtual IEnumerable<Asset> Assets { get; set; }
}
public class Asset : Entity
{
public string Name { get; set; }
public string Description { get; set; }
}
and here is my model configuration for ODATA
public class AssetModelConfiguration : IModelConfiguration
{
public void Apply(ODataModelBuilder builder, ApiVersion apiVersion)
{
var org = builder.EntitySet<Asset>("asset").EntityType;
org.HasKey(x => x.ExternalId);
org.Ignore(x => x.Id);
}
}
The strange thing is if I put that ExternalId in "Asset" class, it is working. Id property is the primary key while the "ExternalId" is marked as AlternateKey in the DBModel configuration.
am I missing something in my odata configuration? already tried many things but couldn't find a good answer. Any help would be appreciated!

Entity Framework 6 Table per Hierarchy (TPH) bug

I've created an abstract class with some base properties:
public abstract class BaseModel
{
public BaseWishModel()
{
}
[Key]
public int Id { get; set; }
public virtual string Title { get; set; }
public bool IsPublished { get; set; }
public bool IsSpam { get; set; }
}
My item class:
public class PrivateItem : BaseModel
{
[NotMapped]
public string PurposesIds { get; set; }
}
My OnModelCreating method:
modelBuilder.Entity<BaseModel>()
.Map<PrivateItem>(r => r.Requires("Discriminator").HasValue((int)Enums.Type.Private))
.ToTable("Items");
When I save the data it's generates next sql:
INSERT [dbo].[Items]([Title], [IsPublished], [ShortDescription1], [ShortDescription2], [Discriminator])
I don't know why it's generates ShortDescription1 and ShortDescription1
As, according to your comment, you have other classes inheriting from BaseModel, and with no other configuration from you, EF uses TPH by default.
Basically this leads to a single table for all the classes hierarchy.
As all classes of the hierarchy are persisted in the same table when an insert, for one class, is done, all columns (of the hierarchy) are populated. The non used by the class columns are populated by null or default value.
This bring the ShortDescription1 and ShortDescription2 in your insert query.

How to map a list of component in Entity Framework 5?

I'm a NHibernate user and NHibernate allows me to create a very fine-grained model.
I'm porting an application from NHibernate to Entity Framework.
NHibernate allows me to define things like:
public class User : DomainEntity
{
public virtual Name Name { get; set; }
...
public virtual ICollection<LogonInformation> LogonInformations { get; set; }
}
public class Name
{
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
public class LogonInformation
{
public virtual string Ip { get; set; }
public virtual DateTime Date { get; set; }
}
Where Name and LogonInformation are mapped as < componentes >.
In special case,when NHibernate is creating the database, creates the UserId in LogonInformation table.
How can I do this using EntityFramework 5?
I've tried using the Complex Types but it does not seems to work since I still get the following exception:
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType
'LogonInformation' has no key defined. Define the key for this
EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet
'LogonInformations' is based on type 'LogonInformation' that has no
keys defined.
Your exception is complaining about LogonInformation not having a primary key. In order to establish a primary key you add the attribute Key to the property you want to be the primary key, for instance, if Ip is your primary key, your code would be:
public class LogonInformation
{
[Key]
public virtual string Ip { get; set; }
public virtual DateTime Date { get; set; }
}
UPDATE:
If you can't change LogonInformation you can set its primary key with Fluent-API (I don't like this way but it could solve your problem). In order to do that, you need to override the OnModelCreating method in your context like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<LogonInformation>().HasKey(logInfo => logInfo.Ip);
}

Must pass connection string to EF 5 DbContext code first else Command Exception

I m just using EF 5.0 and I've recreated a very simple DbContext that was working as is with EF 4.1.
Here context and model
public class AgenciesDatabaseContext : DbContext
{
public DbSet<Agency> Agencies { get; set; }
}
[Table("QryAgency")]
public class Agency
{
[Key]
public string CardCode { get; set; }
public string DisplayName { get; set; }
public string CardFName { get; set; }
public string Address { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
}
I set in global.asax initializer for this context as null because the table already exists
Database.SetInitializer<ExtranetCentralizerContext>(null);
Here's the connection string in web.config :
<add name="AgenciesDatabase" providerName="System.Data.SqlClient" connectionString="..."/>
When I try to use the DbContext in the repository I get this error :
InnerException = {"Invalid column name '...'.\r\n Invalid column name '...'.\r\nInvalid column name '...'."}
It's strange because I could see that there is not connection made to my database.
What I don't understand is that I can make it work if I pass the connection string to the context like this :
public class AgenciesDatabaseContext : DbContext
{
public DbSet<Agency> Agencies { get; set; }
public AgenciesDatabaseContext ()
: base("AgenciesDatabase")
{
}
}
There everything work fine. So my question is : isn't EF suposed to use the connection string that matches it's name (in this case AgenciesDatabase) ??? What makes it fail in this case ?
in your app.config the name should be AgenciesDatabaseContext, not only AgenciesDatabase.