Insert null fails with Model First EF - asp.net-mvc-3

I'm using a context generated from an EDMX for a mvc3 webapp. I'm getting a NULL insert fails error on an entity
[Serializable]
[DataContract(IsReference = true)]
[EdmEntityType(NamespaceName = "Model", Name = "Thing")]
public class Thing: EntityObject
{
public RolloverEntry();
[DataMember]
[EdmScalarProperty(EntityKeyProperty = true, IsNullable = false)]
public int id { get; set; }
[SoapIgnore]
[EdmRelationshipNavigationProperty("Model", "FK_ThingStep1", "Step1")]
[DataMember]
[XmlIgnore]
public EntityCollection<Step1> Step1 { get; set; }
[SoapIgnore]
[EdmRelationshipNavigationProperty("Model", "FK_ThingStep2", "Step2")]
[XmlIgnore]
[DataMember]
public EntityCollection<Step2> Step2 { get; set; }
public static Thing CreateThing(int id);
}
Data access to other parent-child relationships are working and persisted correctly - I can't seem to find what's wrong with this table tho - any ideas appreciated
Exception Recieved:
{"Cannot insert the value NULL into column 'id', table 'myapp.dbo.Thing'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}
Thanks

I'm guessing you need some sort of hint in your model that the database should generate the ids for the id column. You might want to see if StoreGeneratedPattern is set to Identity for your model property id or something along those lines.

Related

Using foreign Key in DbInitialize class. Code First

I have two entities
public class Datatype
{
[Key]
public int Id { get; set; }
[StringLength(96)]
public string DataTypeName { get; set; }
}
public class Attribute
{
[Key]
public int Id { get; set; }
[StringLength(96)]
public string Attribute_Name { get; set; }
[ForeignKey("Datatype")]
public int? DatatypeId { get; set; }
public virtual Datatype Datatype { get; set; }
}
In DataBase Initialize I have this code
Datatype dt = new Datatype();
dt.DataTypeName = "text";
context.datatypes.Add(dt);
//Above code is working fine. And After execution I can see
//in records a row.. with id=1 and datatype=text
Attribute at = new Attribute();
at.Attribute_Name = "Description";
//at.DatatypeId = 1; But if I uncomment this line
context.attributes.Add(at); // Then This Gives Following Error
The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_dbo.Attributes_dbo.Datatypes_DatatypeId". The conflict occurred in database
"dyescan", table "dbo.Datatypes", column 'Id'
Assuming that the above code executes before either of the two objects have been saved to the database then it will not work simply because your object 'dt' will not have an ID of 1 before it's been saved to the database and therefore you cannot associate with attribute on '1' YET!
Instead you should not set the 'DatatypeId' but simply set the 'Datatype' like so:
at.Datatype = dt;
This will leave entity framework to figure out what the actual foreign key associated should/would be when savechanges is called.

Automapper and Linq with joined tables, populating ViewModel properties

Having just figured out how to populate my ViewModel from a model using Automapper, I am now onto the next challenge – populating the ViewModel properties from a joined table.
The image below depicts my simple database.
My ViewModel class is defined as:
public class PersonViewModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<int> Age { get; set; }
public Nullable<int> SuffixId { get; set; }
public string PersonStatus { get; set; }
public string PersonPreference { get; set; }
public virtual Suffix Suffix { get; set; }
} enter code here
Note the additional fields of PersonStatus and PersonPreference that will come from joining PersonInfo to Person.
Here is the code I use to instantiate my mapping configuration:
Mapper.CreateMap<PersonViewModel, Person>();
Mapper.CreateMap<Person, PersonViewModel>();
And now the code to populate the ViewModel
List<PersonViewModel> persons = null;
using (var context = new DemoEntities())
{
persons = (from p in context.People.AsEnumerable()
join i in context.PersonInfoes on p.Id equals i.PersonId
select Mapper.Map<PersonViewModel>(p)).ToList();
return persons;
}
How would I populate the two joined properties (PersonStatus and PersonPreference) from this setup?
Thanks in advance!
AutoMapper can automatically flatten an object structure if the source and target classes meet some requirements.
The source class, the class that the mapping starts from, should have reference property to the related class. In you case: Person.PersonInfo (1:1, but n:1 will also work).1
The target class should contain property names that allow AutoMapper to resolve the property path to the referenced object. in your case: PersonViewModel.PersonInfoStatus, so AutoMapper will see that there's a property PersonInfo in the source object and a property Status in the referenced object.
If you've got these things in place, you can do
persons = context.People.Project().To<PersonViewModel>().ToList();
The Project().To syntax is a relatively new API that allows working on IQueryables. For more details see Does AutoMapper support Linq?.
You will see that this sends a JOIN query to the database.
1AutoMapper can also aggregate/flatten associated collections, but that's a different chapter.

Get The Table Name Of Model In T4 Template

I am using MVC4 ,T4 Scaffolding and EF5.
I Created a model,
namespace wbtest.Models
{
[Table(name: "Pay_Employees_Mst", Schema = "Test")]
public class Employee
{
public int EMPLOYEE_ID { get; set; }
public string EMPLOYEE_CODE { get; set; }
}
}
I need to get the annotation of table name "Pay_Employees_Mst" for db context .Currently getting ModelName Employee.
Please Help.
I got it through,
String entityName1 = (context as System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext
.CreateObjectSet<Employee>()
.EntitySet.Name;

Entity framework is making the id null on insert

I'm getting the following error when I try to insert a new row in one of my relational tables. I have the following two models:
public class CompanyCredit
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int creditId { get; set; }
public int planCredit { get; set; }
public DateTime? PlanCreditExpirationDate { get; set; }
}
And
public class CompanyInformation
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
[Required]
[DisplayName("Company Name:")]
public string companyName { get; set; }
public string timeZone { get; set; }
//navigation Properties
public virtual CompanyCredit Credits { get; set; }
}
And this Relation in the dbContext
modelBuilder.Entity<CompanyInformation>().HasOptional(e => e.Credits);
I'm trying to add a record inside CompanyCredit table like so:
if (_company.Credits == null)
{
var _credits = new CompanyCredit();
_credits.planCredit = 200;
_credits.PlanCreditExpirationDate = System.DateTime.UtcNow.AddMonths(1);
_company.Credits = _credits;
repo.InsertOrUpdate(_company, User.Identity.Name);
}
And Finally Insert or update just marks Company as changed and _credit as added like so:
_db.Entry(_credits).State = System.Data.EntityState.Added;
_db.Entry(Company).State = System.Data.EntityState.Modified;
_db.SaveChanges();
When this runs I get the following Error that I just can't seem to find the reason to.
Cannot insert the value NULL into column 'creditId', table 'Project.dbo.CompanyCredits'; column does not allow nulls. INSERT fails.
The statement has been terminated.
Thank in advanced for your help.
I found the problem was in the attribute [DatabaseGenerated(DatabaseGeneratedOption.Identity)] this should have been [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
I thought I would post this so others might benefit from it.
Could you please try reversing the order of entity state modification, just before the saveChanges call
_db.Entry(Company).State = System.Data.EntityState.Modified;
_db.Entry(_credits).State = System.Data.EntityState.Added;
_db.SaveChanges();

data annotation where two properties are unique in mvc 3

I have following Category table as below and I have use Entity framework model first:
ID => int , primary key , unique
CategoryName => varchar(50)
ParentCategoryID => int
I have applied unique constraint for two column categoryName and ParentCategoryID by executing following query:
ALTER TABLE Category
ADD CONSTRAINT UQ_YourTable_ConstraintName UNIQUE(CategoryName, ParentCategoryID)
Here, what I want is that to validate the input if the commbine form of categoryName and ParentCategoryID is unique using dataannotation. So, I have created the partial class for category as:
[MetadataType(typeof(TestEntityValidation))]
public partial class Category{
}
public class TestEntityValidation{
//............ data annotation
public string CategoryName{ get; set; }
//............ data annotation
public string ParentCategoryID { get; set; }
}
what could be code for data annotation so that Combination of CategoryName and ParentCategoryID is always unique and show error if duplicate data is entered by user.
I dont think you can do this using Data Annotation, but here is what you could do
public ActionResult Validate(SomeModel model)
{
// check for this condition with db using the 'model'
if(combination_is_NOT_unique)
{
ViewBag.Message = "Not Unique";
return View("NameOfTheView");
}
// else
do the normal stuff
}

Resources