When Adding Data Annotation Attribute it's throwing Exception - sql-server

public class Employee {
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public decimal Salary { get; set; }
public string Email { get; set; }
}
public class EmployeeContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
}
When I'm adding Data Annotation [Required(ErrorMessage = "Employee Name is required")] to the Name property it's throwing an InvalidOperationException. As I was trying to fix the bug I'm getting these suggestions online:
It means one of your classes use in the EmployeeContext has changed, but the database hasn't been updated so is now out of date. You need to update this use Code First migrations.
When I'm making the following changes its throwing an error now
public class Employee {
[Key]
public int Id { get; set; }
[DisplayName("Employee Name")]
[Required(ErrorMessage = "Employee Name is required")]
[StringLength(35)]
public string Name { get; set; }
public string Address { get; set; }
public decimal Salary { get; set; }
public string Email { get; set; }
}
Snapshot:
Questions:
If a Database Table is created is it possible to change a column ?
When adding a Data Annotation Attribute it's throwing an Exception, why is the database table column not changing ?
Addicted to your tutorials now

User Migration for update database structure
Without [Required] filed Name allow null (varchar(x) null), with [Required] Name change not null (varchar(x) not null)
If in database threre are rows with nullable Name, can be error on update (with migration)

Related

EF Core query full join between many-to-many relation

I'm working with EF core and I have a many-to-many relation between STUDENTS and SUBJECTS, like this:
public class StudentDetail
{
[Key]
[JsonPropertyName("Id")]
public int Id { get; set; }
[Required]
[Column(TypeName ="nvarchar(50)")]
[JsonPropertyName("Name")]
public string Name { get; set; }
[JsonPropertyName("StudentSubjects")]
public virtual IEnumerable<StudentSubject> StudentSubjects {get; set;}
}
public class SubjectDetail
{
[Key]
[JsonPropertyName("Id")]
public int Id { get; set; }
[Required]
[Column(TypeName = "nvarchar(20)")]
[JsonPropertyName("SubjectName")]
public string SubjectName { get; set; }
[Required]
[JsonPropertyName("Teacher")]
public virtual TeacherDetail Teacher { get; set; }
[JsonPropertyName("StudentSubjects")]
public IEnumerable<StudentSubject> StudentSubjects { get; set; }
}
public class StudentSubject
{
[JsonPropertyName("StudentId")]
public int StudentId { get; set; }
[JsonPropertyName("Student")]
public StudentDetail Student { get; set; }
[JsonPropertyName("SubjectId")]
public int SubjectId { get; set; }
[JsonPropertyName("Subject")]
public SubjectDetail Subject { get; set; }
[Required]
[Column(TypeName = "nvarchar(3)")]
[JsonPropertyName("Grade")]
public string Grade { get; set; }
}
I create my Databse using migrations, so after I did the migration, the database was created like this:
I need a query that bring me all the Subjects with their teacher and grade of an specific Student. I was tryng doing it like this:
var subjects = await _context.StudentSubject
.Include(s => s.Subject)
.Where(sid => sid.StudentId == student.Id)
.Select(st => st.Subject)
.Include(t => t.Teacher)
.ToListAsync();
But I'm getting an ERROR saying that I'm tryng to use Include(); on a non Queryable Entity. Anyone know what am I doing wrong?
Include will only work if you are having a link between two table and that is defined by keyword Virtual in C# classes. Please use public virtual ICollection instead of public IEnumerable and follow the link for more details. If you still wants to continue with same class then try using join in Linq queries.

SQL Server the column name is specified more than once in the set clause. Entity framework issue

When I do an insert using EF6, I get this error
The column name 'employee_id' is specified more than once in the SET clause. A column cannot be assigned more than one value in the same SET clause. Modify the SET clause to make sure that a column is updated only once. If the SET clause updates columns of a view, then the column name 'employee_id' may appear twice in the view definition
My models looked like this:
public class Entity
{
public Entity()
{
IsActive = true;
IsDeleted = false;
DateCreated = DateTime.Now;
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ID { get; set; }
public int CompanyID { get; set; }
public int SubID { get; set; }
public DateTime DateCreated { get; set; }
public bool IsTransient()
{
return EqualityComparer<long>.Default.Equals(ID, default(long));
}
public bool IsDeleted { get; set; }
public bool IsActive { get; set; }
}
public partial class NextOfKin : Entity
{
[Required]
public long employee_id { get; set; }
[StringLength(100)]
[Required]
public string nok_first_name { get; set; }
[StringLength(100)]
[Required]
public string nok_last_name { get; set; }
[StringLength(300)]
[Required]
public string nok_address { get; set; }
[StringLength(100)]
public string nok_email { get; set; }
[StringLength(100)]
public string nok_phone { get; set; }
[StringLength(100)]
public string nok_employer { get; set; }
[StringLength(300)]
public string nok_work_address { get; set; }
[StringLength(100)]
[Required]
public string nok_relationship { get; set; }
public virtual Employee Employee { get; set; }
}
public class Employee : Entity
{
//Person Records
public long UserId { get; set; }
public int TitleId { get; set; }
public int? ReligionId { get; set; }
public string SerialNo { get; set; }
[StringLength(100)]
[Required]
public string FirstName { get; set; }
[StringLength(100)]
[Required]
public string LastName { get; set; }
}
My insert code into next of kin was like this.
NextOfKin nextOfKin = new NextOfKin();
nextOfKin.employee_id = newEmployee.ID;
nextOfKin.nok_first_name = "Friday";
nextOfKin.nok_last_name = "Ben";
nextOfKin.nok_address = "XXX";
nextOfKin.nok_email = "xa#xo.com";
nextOfKin.nok_phone = "023938494";
nextOfKin.nok_employer = "50 Queens Street";
nextOfKin.nok_work_address = "51 Queens Street";
nextOfKin.nok_relationship = "Neighbour";
db.NextOfKins.Add(nextOfKin);
db.SaveChanges();
I got an error like this using EF Core
'PropertyNameID' is specified more than once in the SET clause or
column list of an INSERT. A column cannot be assigned more than one
value in the same clause. Modify the clause to make sure that a column
is updated only once. If this statement updates or inserts columns
into a view, column aliasing can conceal the duplication in your code.
It turned out that I had the case wrong in my relatonship
In My business object I had the foreign key set with the wrong case.
public int PropertyNameID { get; set; }
[ForeignKey("PropertyNameId")] public virtual PropertyNameExt PropertyName { get; set; }
Should have been
[ForeignKey("PropertyNameID")] public virtual PropertyNameExt PropertyName { get; set; }
To fix this, remove the relationship on next of kin model, then do migration.
To remove, remove public virtual Employee Employee { get; set; } from NextOfKin model.
The reason for this issue is as follow:
Relationships are only created properly if you name the reference property properly. In this case you should use EmployeeID instead of employee_id for the relationship between next of kin and employee.
The Employee model does not have a link back to the next of kin model. If it's a one to many you can add the property below to the Employee model.
public virtual List NextOfKins{get; set;} //if you need lazy loading
or
public List NextOfKins{get; set;} //if you don't need lazy loading

Business Rule errors not going away when data is valid

I am using Orc.FluentValidation and I have:
[ValidatorDescription(nameof(Customer), ValidationResultType.Error,
Orc.FluentValidation.ValidationType.BusinessRule)]
public class CustomerBusinessRuleValidator : AbstractValidator<Customer>
{
public CustomerBusinessRuleValidator()
{
RuleFor(x => x.Addresses).Must(x => x != null && x.Count > 0 && x.Any(add => add.IsCurrent))
.WithMessage("Customer object is required to have at least 1 current address.");
}
}
CustomerAddress
public class CustomerAddress : Entity
{
[DomainSignature] public Address Address { get; set; }
[DomainSignature] public Lookup AddressType { get; set; }
[DomainSignature] public bool IsCurrent { get; set; }
}
Customer
public class Customer : Entity
{
[DomainSignature]
public string Code { get; set; }
public Gender Gender { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public DateTime DateOfBirth { get; set; }
public Lookup PlaceOfBirth { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public ICollection<CustomerAddress> Addresses { get; set; }
public Lookup Occupation { get; set; }
public IdDocument Id1 { get; set; }
public IdDocument Id2 { get; set; }
}
On the View even after a CustomerAddress with IsCurrent = true is added for the Customer, the message still shows. Also, I am not sure why some field-bound controls show the error and others not _this is not a field validation rule.
Is there like a method call to be done after adding the CustomerAddress to the Addresses collection?
i.imgur.com/eecAFuJ.png
Make sure you raise a property changed on the whole collection for error validation (e.g. RaisePropertyChanged(nameof(MyCollection)), otherwise the UI can't update the validation results.
Also, I am not sure why some field-bound controls show the error and
others not _this is not a field validation rule.
This is probably because of the default styles you are using. For most of the controls, Orchestra creates an error template (decorator), but not every control had this. We've been working on adding these last week, so I recommend to try out the latest alpha of Orchestra & Orc.Controls.
Also make sure to set ValidateOnDataErrors and NotifyOnValidationErrors on the binding to show the validation in the UI.

Using computed column in .net core

I am trying to use computed column in my project, but I am facing the some error.
Column 'inserted.TotalMarks' cannot be referenced in the OUTPUT clause because the column definition contains a subquery or references a function that performs user or system data access. A function is assumed by default to perform data access if it is not schemabound. Consider removing the subquery or function from the column definition or removing the column from the OUTPUT clause.
Model
public partial class LMS_SurveyUser
{
public LMS_SurveyUser()
{
}
[Key]
public int SurveyUserID { get; set; }
public int SurveyID { get; set; }
public int UserID { get; set; }
public bool? IsCompleted { get; set; }
public DateTime? ExpiryDate { get; set; }
public int? MarksObtained { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public int? TotalMarks { get; set; }
public int LastPageAccessed { get; set; }
public int? WhoCreated { get; set; }
public DateTime? WhenCreated { get; set; }
public int? WhoModified { get; set; }
public DateTime? WhenModified { get; set; }
}
While creating the record with above mentioned it does not gives any error, but if I try to update the existing record then it gives the above mentioned error.
I have configured SQL function in the database for column 'TotalMarks'. I have tried with the fluent mapping also, but it gives the same error.
And in the 'TotalMarks' computed column specification I write this formula:
([dbo].[LMSFN_CalculateTotalMark]([SurveyID],[UserID]))
I am inserting/updating record like below,
Inserting Record
public void InsertSurveyUserDetails(LMS_SurveyUser model)
{
dbcontext.Add(model);
dbcontext.SaveChanges();
}
Updating Record
public void UpdateSurveyUserDetails(LMS_SurveyUser model)
{
dbcontext.Update(model);
dbcontext.SaveChanges();
}
Any help on this appreciated !

Questions About Database

I write chat in C# with Entity Framework
This is my code
public class User
{
[Key]
public long id { get; set; }
public List<UserMessages> userMessages { get; set; }
}
public class UserMessages
{
[Key]
public long Id { get; set; }
public long ChatMateId { get; set; }
public string text { get; set; }
public DateTime? dateTime { get; set; }
}
Entity Framework code-first forced me to put on the Id field in UserMessages class attribute [Key] , I don't need this field at all because UserMessages is weak entity that will point to id of User
Can I delete long Id from sql table after ef create the table, without any problems?
No, you can't. EF requires that all tables have a [Key] on them, or it will blow up. Even when mapping to SQL Views (as I've learned the hard way, believe me).
In your case, you should actually be using a proper Foreign Key in that table also, like so:
public class UserMessages
{
[Key]
public long Id { get; set; }
[ForeignKey("User")]
public long UserId { get; set; }
public long ChatMateId { get; set; }
public string text { get; set; }
public DateTime? dateTime { get; set; }
public User User { get; set; }
}

Resources