code:
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data.Entity;
namespace explorer.Models
{
[Table(Name = "Meta")]
public class MetaD
{
[System.ComponentModel.DataAnnotations.Key]
[Column (IsPrimaryKey=true)]
public int MId{ get; set; }
[Column]
public string Name { get; set; }
[Column]
public string Desc { get; set; }
[Column]
public DateTime? Updated { get; set; }
[Column]
public Boolean? Active { get; set; }
}
public class mContext : DbContext
{
public DbSet<MetaD> MetaData { get; set; }
}
}
The above works but when running it gives the error: The model backing the 'mContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
Find/Replace (IsPrimaryKey=true) to , Key
Related
How can I update Model from Database and keep my models DataAnnotations without change ?
Always after update model from database I need to add
using System.ComponentModel.DataAnnotations;
again for each class and add
[Display(Name = "Name")]
for all fields and this take long time with every single update
How can I skip this step and update model from database and keep that settings ?
Use the MetadataTypeAttribute class to achieve the solution you are looking for.
The documentation contains detailed description how to use is.
As an example, let say you have an entity class Order with the following properties:
public class Order
{
public int OrderId { get; set; }
public string OrderDescription { get; set; }
public string BillingAddress { get; set; }
… // another properties
}
The solution is to add partial declaration to the model class and to create a second partial class that contains the metadata:
using System;
using System.ComponentModel.DataAnnotations;
[MetadataType(typeof(OrderMetaData))]
public partial class Order
{
public int OrderId { get; set; }
public string OrderDescription { get; set; }
public string BillingAddress { get; set; }
… // another properties
}
Creating a meta data class with required annotations:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public partial class OrderMetaData
{
[HiddenInput(DisplayValue=false)]
public int OrderId { get; set; }
[Display(Name="Description")]
public string OrderDescription { get; set; }
[Display(Name = "Billing Address")]
public string BillingAddress { get; set; }
}
The meta data class only needs to contain properties that you want to apply annotations.
Take care the entity class and the meta data class have consistent namespaces.
I am developing an application in asp.net mvc. I use entity framework as ORM. I have a problem. To use javascript unobstrusive validation, I need to add annotation to model objects. For example; [Required], [EMailAddress]. But when we add something to the database and update it, all model classes are override, and all annotations disappear. Or, as soon as you open edmx, automatic model classes are automatically override. How can I solve this problem. There are dozens of screens and classes, the slightest change in edmx erases the annotation in all classes, causing huge waste of time.
// <auto-generated>
using System.ComponentModel.DataAnnotations;
namespace MerinosSurvey.Models
{
using System;
using System.Collections.Generic;
public partial class Surveys
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Surveys()
{
this.SurveyQuestions = new HashSet<SurveyQuestions>();
this.SurveyCustomers = new HashSet<SurveyCustomers>();
}
public int SurveyId { get; set; }
[Required(ErrorMessage = "Plase enter survey name.")]
public string SurveyName { get; set; }
[Required(ErrorMessage = "Please enter survey description.")]
public string SurveyDescription { get; set; }
// [DataType(DataType.Date)]
public System.DateTime? CreatedDate { get; set; }
//[DataType(DataType.Date)]
public System.DateTime? UpdatedDate { get; set; }
public int CreatedUserId { get; set; }
public bool IsActive { get; set; }
public bool Status { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<SurveyQuestions> SurveyQuestions { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<SurveyCustomers> SurveyCustomers { get; set; }
public string Token { get; set; }
}
}
Editted for
Metadata
Surveys Partial & Metadata
//PartialClass
[MetadataType(typeof(SurveyMetadata))]
public partial class Surveys
{
}
//Metadata
public partial class SurveyMetadata
{
public int SurveyId { get; set; }
[Required(ErrorMessage = "Lütfen anket adını giriniz.")]
public string SurveyName { get; set; }
[Required(ErrorMessage = "Lütfen anket açıklamasını giriniz.")]
public string SurveyDescription { get; set; }
// [DataType(DataType.Date)]
public System.DateTime? CreatedDate { get; set; }
//[DataType(DataType.Date)]
public System.DateTime? UpdatedDate { get; set; }
public int CreatedUserId { get; set; }
public bool IsActive { get; set; }
public bool Status { get; set; }
public virtual ICollection<SurveyQuestionMetadata> SurveyQuestionMetadatas { get; set; }
public virtual ICollection<SurveyCustomerMetadata> SurveyCustomerMetadatas { get; set; }
public string Token { get; set; }
}
GetData Ajax Event
// GET: Survey
public ActionResult GetData()
{
using (MerinosSurveyEntities entity = new MerinosSurveyEntities())
{
List<Surveys> surveys = entity.Surveys.Where(x => x.IsActive && x.Status)
.OrderBy(x => x.SurveyId).ToList();
return Json(new { data = surveys }, JsonRequestBehavior.AllowGet);
}
}
How I should change my GetData event.And what list should go to the client side??
Best Practice is, use ViewModel[Not Entity/Model classes] to manipulate / play at Client Side.
So use ViewModel, Inherit Model classes and then use Annotations
For eg.
Public class ViewModelClass: ModelClass
{
[Required("First Name is Required")]
Public String FirstName {get; set;}
}
For do such thing you can use partial classes and use "ModelMetadataType" in .net core annotation above your class.
lets do it in code:
this is your model that is created in edmx:
public partial class Student{
public string FirstName {get; set;}
}
first of all you have to create a partial class in another file with same name as student class and be careful its name space should be same as above class. (classes must be out of edmx file)
[ModelMetadataType(typeof(StudentMetaData))]
public partial class Student{
}
and at the end you must create your metadata class like this:
public class StudentMetaData{
[Display(name="First Name")]
public string FirstName {get; set;}
}
now you can update your edmx file without changing the data annotations in your metadata classes.
https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.metadatatypeattribute?view=netframework-4.8
Working from memory at the moment, but the EF classes are always partial so create another partial implementation of the same class, then add the Interface and Metadatatype binding to that.
// Entity Framework Model
public partial class User
{
public string Email { get; set; }
public string Password { get; set; }
}
// Your Interface with data annotations
public interface IUser
{
[Required]
string Email { get; set; }
[Required]
string Password { get; set; }
}
// Partial Model appling the interface to the entity model
[MetadataType(typeof(IUser))]
public partial class User : IUser
{
}
Under this approach, in the future, you only need to worry about updating your interface should you add new properties
Copy the generated CS files (the one's with your table names) that you've already added your annotations to, to another folder, then overwrite the newly generated ones, I do it this way and shall continue to until there's a more hassle-free way to do it.
I am having issues trying to map two fields that are foreign keys into the same table. The use case is for a modifier and creator. My class already has the Ids, and then I wanted to add the full User object as virtual.
I am using a base class so that each of my tables have the same audit fields:
public class Entity
{
public long? ModifiedById { get; set; }
public long CreatedById { get; set; } = 1;
[ForeignKey("CreatedById")]
public virtual User CreatedByUser { get; set; }
[ForeignKey("ModifiedById")]
public virtual User ModifiedByUser { get; set; }
}
The child class is very simple:
public class CircleUserSubscription : Entity
{
[Required]
public long Id { get; set; }
public long SponsorUserId { get; set; }
[ForeignKey("SponsorUserId")]
public virtual User User { get; set; }
public long TestId { get; set; }
[ForeignKey("TestId")]
public virtual User Test { get; set; }
}
This is a standard junction table.
When I try to generate the migration, I am getting errors that I don't understand fully.
Unable to determine the relationship represented by navigation property 'CircleUserSubscription.User' of type 'User'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
I tried what this answer had, but the code is basically the same: https://entityframeworkcore.com/knowledge-base/54418186/ef-core-2-2---two-foreign-keys-to-same-table
An inverse property doesn't make sense since every table will have a reference to the user table.
For reference, here is the User entity:
public class User : Entity
{
public long Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
I am hoping you all can help me out, TIA :)
EDIT: One thing to note, all of this worked fine when the entity class was as follows:
public class Entity
{
public long? ModifiedById { get; set; }
public long CreatedById { get; set; } = 1;
}
It was only after I added the entity that things went awry.
I have a connection to PostgreSQL using Entity Framework.
When retrieving data, everything works okay, also migrations are working well, the problem is during insertion of the data.
I assume its due to the ID not being automatically generated, but since I'm new to Entity Framework, I do not know how to move forward.
Here is my AddUser function:
public Task<EntityEntry<UserModel>> AddUser(UserModel user) => this.context.Users.AddAsync(user);
This is the corresponding model class:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace WishareIntegrationApi.Entities
{
public class UserModel
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string token { get; set; }
public string displayName { get; set; }
public string photoURL { get; set; }
public string email { get; set; }
public DateTime registeredAt { get; set; }
public string birthday { get; set; }
}
}
When I add data into table manually and fill in the ID it will insert the data, if the ID is not part of the insert query, it will fail even tho it should be auto_increment.
The database is generated from the code using migrations.
Any ideas?
As Evk stated, I was missing call of the SaveChanges function.
I have an error:
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'DynamicMenu' has no key defined. Define the key for this EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'ambt_Dynamic_Menu' is based on type 'DynamicMenu' that has no keys defined.
in helper class which code is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Data.Models;
using Data;
namespace Ambermoda.Web
{
public class MenuHelper
{
public static List<DynamicMenu> GetMenu()
{
DataContext db = new DataContext();
List<DynamicMenu> list = db.ambt_Dynamic_Menu.ToList();
return list;
}
}
}
so I have no idea how can I solve it. I checked everything what (in my opinion) can generate this error, but with any results.
I sam similar posts but any of them doesn't solve my problem.
If anybody have some idea, pleas write it :)
Thanks!
Some more code
DynamicMenu.cs
[Table("abmt_Dynamic_Menu")]
public class DynamicMenu
{
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int dmn_id { get; set; }
public string dmn_code { get; set; }
public string dnm_parent_code { get; set; }
public string dnm_title { get; set; }
public string dnm_title_en { get; set; }
public int dnm_order { get; set; }
}
DataContext.cs
public class DataContext : DbContext
{
public DataContext() { }
public DbSet<DynamicMenu> ambt_Dynamic_Menu { get; set; }
}
Connection string:
<add name="DataContext" providerName="System.Data.SqlClient" connectionString="Data Source=Mikasasa-lap\Mikasasa;Database=Ambermoda;Integrated Security=True;Pooling=False;"/>
According to source code you provided, you're working with the Code First approach.
CF assumes that class should have property named "Id" by the naming convention, and this property will be treated as primary key.
Otherwise, you should manually declare primary key via attribute [Key] or using fluent API (see EntityTypeConfiguration.HasKey method).
You need to inform what field is your database Primary Key. Use the attribute Key to do this:
[Table("abmt_Dynamic_Menu")]
public class DynamicMenu
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int dmn_id { get; set; }
public string dmn_code { get; set; }
public string dnm_parent_code { get; set; }
public string dnm_title { get; set; }
public string dnm_title_en { get; set; }
public int dnm_order { get; set; }
}
Check whether the DyanmicMenu table has primary key