Hali
Hali

Reputation: 591

Entity Type has no key defined error while using fluent mapping Entity Framework

I am using Entity Framework with fluent mapping.

In my application I want to fetch data from a view which is not having a key.

I have written a entity mapping for fluent api and a method to fetch data from view

When I tried to test the method, I get an error:

Entity Type has no key defined, Define a key for this entity type

Can I fetch data from view with out a key using Entity Framework with fluent. Below is the entity class:

public class WeatherData : BaseModel
{
    public DateTime ReportDateTime { get; set; }
    public string VendorName { get; set; }
    public string WeatherTypeCd { get; set; }
    public string WeatherStationCd { get; set; }
    public DateTime WeatherDate { get; set; }
    public int Interval { get; set; }
    public string IntervalTypeCd { get; set; }
    public string WeatherValueTypeCd { get; set; }
    public decimal ValueMax { get; set; }
    public decimal ValueMin { get; set; }
    public decimal ValueAvg { get; set; }
    public string Unit { get; set; }
    public int DegreeDayBase { get; set; }
    public string UpdateUser { get; set; }
    public DateTime UpdateDt { get; set; }
    public int VendorId { get; set; }
    public int WeatherStationId { get; set; }
    public int WeatherTypeId { get; set; }
    public int IntervalTypeId { get; set; }
    public int WeatherValueTypeId { get; set; }
}

This is the mapping class:

public class WeatherDataMap : EntityTypeConfiguration<WeatherData>
{
    public WeatherDataMap() : base()
    {
        this.ToTable("dbo.vw_WeatherData");
    }
}

I cannot change the view, I only have read permissions.

Upvotes: 1

Views: 1300

Answers (1)

Aria
Aria

Reputation: 3844

There is no problem if your table or view does not have primary key, but to avoid that mentioned exception your model must have PK so as the EF-Code First documentation says you can define Key a PK on more then one column or on one column so your model would be like :

public partial class WeatherData : BaseModel
{
    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int VendorId { get; set; }

    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int WeatherStationId { get; set; }

    [Key]
    [Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int IntervalTypeId { get; set; }

    [StringLength(50)]
    public string VendorName { get; set; }

    [StringLength(50)]
    public string WeatherTypeCd { get; set; }
}

To use Find method of a DbSet you must take this order for the key parameters.

But please note if you generate EF-Code first model by POCO or Wizard the EF define all the int columns as the primary key as you can see in the above model, but you can define one prop as key but you should be sure there is no duplicated field which you defined as the key otherwise you should combine multiple columns as the primary key...

The other way is use Fluent Api to define key as the below code in OnModelCreating of your context:

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<WeatherData>().Property(a => a.VendorId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        modelBuilder.Entity<WeatherData>().Property(a => a.WeatherStationId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        modelBuilder.Entity<WeatherData>().HasKey(w => new
        {
            w.VendorId,
            w.WeatherStationId
        });
    }

Upvotes: 2

Related Questions