my project use ef and reposiroty for communication with database
when i find a record with the id
var applicant = applicantProvider.Get(1020);
Context.Set<TEntity>().Find(id);
then i got exception
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
Additional information: Year, Month, and Day parameters describe an un-representable DateTime.
the data record is :
id DOB SubmitDate CreateDate UpdateDate
1020 01/06/1949 2010-05-12 16:01:39 2010-05-14 16:59:10 2011-05-28 10:22:00
i don't know how i got that error pls help me
My entity Applicant
public class ABGApplicant
public int ABGApplicantID { get; set; }
public DateTime? DOB { get; set; }
public DateTime? SubmitDate { get; set; }
public DateTime? CreateDate { get; set; }
public DateTime? UpdateDate{ get; set; }
this is my main function
IABGApplicantProvider applicantProvider = new ABGApplicantProvider(new GenesisContext());
var applicant = applicantProvider.Get(1020);
this is my ABGApplicantProvider extend repository
public class ABGApplicantProvider : Repository<ABGApplicant>, IABGApplicantProvider
{
public ABGApplicantProvider(DbContext context) : base(context)
{
}
}
This is class Repository
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
public TEntity Get(int id)
{
// Here we are working with a DbContext, not PlutoContext. So we don't have DbSets
// such as Courses or Authors, and we need to use the generic Set() method to access them.
return Context.Set<TEntity>().Find(id);
}
I think your problem is not in your repository but in the data inside your DB...
Check the record with id=1020 and then check the column DOB
Related
I have these models and context in my application :
public class Department
{
public int Id { get; set; }
public string Name { get; set;}
public virtual ICollection<Student> Students { get; set; }
}
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Department Department { get; set; }
}
public class TestContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Department> Departments { get; set; }
}
Below is my code in Program.cs class :
class Program
{
static void Main(string[] args)
{
using (var context = new TestContext())
{
var students = context.Students.SqlQuery("Select * from dbo.Students").ToList();
context.Departments.Load();
Console.WriteLine(students[0].Department.Name);
Console.ReadLine();
}
}
}
Although related object - Department is loaded in the context by the line - context.Departments.Load(), still when the department name is printed in console entity framework fires a query in the database to fetch the related object. Shouldnt this query for related object fetching not be fired since the objects are already loaded in the context. ?
If i change the code to below -
var students = context.Students.ToList();
context.Departments.Load();
Console.WriteLine(students[0].Department.Name);
Then when u access student[0].Department.Name , Ef doestnot fire a sql query to load department property.
Apparently Change Tracker relationship fix-up doesn't work with the combination of Independent Associations and raw SQL queries.
To fix just add Foreign Key property to Student. eg
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
I have a little problem when I try to save an item in my DB using EntityFramework.
My classes looks like:
public partial class Site
{
public int Id { get; set; }
public string Name { get; set; }
public string LongName { get; set; }
public string Adress { get; set; }
public City City { get; set; }
public Country Country { get; set; }
public string VATNumber { get; set; }
}
public class Country
{
public int CountryId { get; set; }
public string Name { get; set; }
public string IsoCode { get; set; }
}
And when I try to create a new site in my controller it works, but when I try to add a link to an existing Country :
if (SiteProvider.GetSiteByName(Site.Name) == null)
{
Site.Country = CountryProvider.GetCountryById(1);//it's working, i see the link to the right country
SiteProvider.Create(Site);
}
public static void Create(Site Site)
{
using (MyDBContext Context = new MyDBContext())
{
Context.Site.Add(Site);
Context.SaveChanges(); //here is the problem
}
}
I got this error:
SqlException: Cannot insert explicit value for identity column in
table 'Country' when IDENTITY_INSERT is set to OFF
Thanks in advance for your help.
Add CountryId property to Site class and when adding a new Site set CountryId instead of Country property
public int CountryId { get; set; }
[ForeignKey("CountryId")]
public Country Country{ get; set; }
You have a slight issue with your use of contexts here. You have used one DBContext instance to load the country (where this country object will be tracked) and then a second DBContext to save the site (where the first country object is a property).
It is preferable to perform all your operations for a single unit of work by using one DB context (that would be shared between your classes) and the responsibility for disposing of it to be handled outside your repository layer.
I am using "CodeFirst Existing Database" and have introduced a stored procedure from mycontext class which seems fine but the entity i am mapping to has a complex type.
MyContext
public virtual List<Student> Get_AllStudents(int year, string classes, string indicators) {
StringBuilder spCommand = new StringBuilder();// = "CALL Get_AllStudents(";
//params object[] parameters;
MySqlParameter[] mySqlParams = new MySqlParameter[]{new MySqlParameter("yearId", year),
new MySqlParameter("classIds", classes),
new MySqlParameter("indicatorList", indicators)};
spCommand.Append("CALL Get_AllStudents(#yearId,#classIds,#indicatorList);");
return this.Database.SqlQuery<Student>(spCommand.ToString(), mySqlParams).ToList<Student>();
}
and my query is
select s.firstname, s.surname,s.IndicatorID from students s
where ClassId in (classIds)
and yearId = yearId
and indicatorId in (indicatorList);
My Student Entity has a complex type "Name"
public class Student
{
public int studentID { get; set; }
public string studentCode { get; set; }
public Name name { get; set; }
public Nullable<System.DateTime> birthdate { get; set; }
}
public class Name {
[Column("surname")]
public string surname { get; set; }
[Column("middlename")]
public string middlename { get; set; }
[Column("firstname")]
public string firstname { get; set; }
[Column("preferredname")]
public string preferredname { get; set; }
}
How do i tell entity framework to map s.firstname and s.surname to map to Student.Name.firstname and Student.Name.surname properties
I havent used import function (as it is giving me some stupid error i dont want to deal with "Your project references the latest version of EntityFramework however EF data provider compatible with this version cannot be found...") can i change some sp settings in mycontext class to expect complex type?
Error
Cannot create a value for property 'name' of type 'DbContexts.Name'.
Only properties of primitive or enumeration types are supported.
I have two DbContext class and some Entities in them. I know this is not good idea to have more than one DbContext but i have to do a lot of works to change my code! so my question is what is the best scenario for add relationship between two Entities with different DbContext?
For example an one to many relationship between User Entity with IdentityDb Context and Comment Entity with SiteDbContext :
public class User : IdentityUser
{
public DateTime JoinDate { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this,DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
public class IdentityDb : IdentityDbContext<ApplicationUser>
{
public IdentityDb() : base("DefaultConnection", throwIfV1Schema: false)
{
}
public static IdentityDb Create()
{
return new IdentityDb();
}
}
public class Comment
{
public int CommentId { get; set; }
[Required]
[StringLength(900)]
public string CommentText { get; set; }
[DataType(DataType.Date)]
public DateTime CommentDate { get; set; }
}
public class SiteDb: DbContext
{
public SiteDb(): base("DefaultConnection")
{
}
public DbSet<Comment> Comments{ get; set; }
}
Short answer: Entity Framework currently doesn't support creating a query which uses more than one context.
For work around: Refer this.
I am using EF version 6.1 and have a mapping problem:
class BasePoco
{
public Guid Id{get;set;}
}
class Student : BasePoco
{
public string Name;
}
public class UserBase : BasePoco
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public string Photo { get; set; }
}
public class UserDetail : UserBase
{
public string MobileNumber { get; set; }
public string EmailID { get; set; }
}
public Enum UserType
{
Student = 1,
User=2
}
the Attendance class
public class Attendance
{
public class UserId {get;set;} // Can be either student or user
public UserType UserType {get;set;}
}
I need to mark attendance for Student as well as User in the same table.
The UserType would determine whether the Id is of a student or User and the primary key would be a combination of UserType and Id.
How can I accomplish this using EF code first approach.
Sorry you cant use multiple type over single property. You do understand, because EF run over metadata. Which use EF know metadata from model class. This is a problem. Attendance table foregin key is multiple table referance and Attendance model contains both model. You should create logical layer for check UserType and access correct model. For example
public class Attendance
{
public UserType userType {get;set;}
public Guid? UserId {get;set;}
public virtual User user {get;set;}
public Guid? StudentId {get;set;}
public virtual Student student {get;set;}
}
now layer class
public class AttendanceUserLayer
{
public static object GetUser(Attendance attendance) {
if (attendance.userType == UserType.User) {
return attendance.User;
} else {
return attendance.Student;
}
}
how to use
Attendance attendance = context.Attendance.FirstOrDefault();
var userOrStudent = AttendanceUserLayer.GetUser(attendance);
if you cannot use the type of object result, write interface both class and set return type that interface.