Daniel
Daniel

Reputation: 150

Exclude underlying objects when storing data using EF6

I have a class Ticket which has some properties. Three of these (View, Task and Key) properties are navigation properties. Those properties already exist in database even before a ticket has been stored. In my application I load those properties from the database first and then create a Ticket object. I need to save only the ticket (not the underlying objects ) to the database with the id to Key, View and Task (these are primery keys in the Ticket table)

[Table("Tickets")]
public class Ticket
{
    [Key]
    public int Id { get; set; }

    public DateTime? Created { get; set; }

    [Required]
    public View View{ get; set; }

    [Required]
    public Key Key { get; set; }

    public Task Task { get; set; }


}

I try to save the Ticket object like this:

        db.Tickets.Add(ticket);
        db.Entry(ticket.Key).State = System.Data.Entity.EntityState.Unchanged;
        db.Entry(ticket.View).State = System.Data.Entity.EntityState.Unchanged;
        db.Entry(ticket.Task).State = System.Data.Entity.EntityState.Unchanged;

db.SaveChanges();

When I try this approach I get the error:

{"Message":"An error has occurred.","ExceptionMessage":"Saving or accepting changes failed because more than one entity of type 'Key' have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the 'HasDatabaseGeneratedOption\" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration.","

Is it even possible to work with Entity Framework this way? Having pre defined data which is loaded to it's objects (Key, View, Task) first and later assign these objects to an object having these properties but then in the entity framework context only adding the parent object, in this case the ticket?

I have also tried to set the underlying objects to null but then I will loose the data for those underlying objects, data I need later on in the application. This is how the underlying objects look like:

    [Table("Views")]
public class View
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Version { get; set; }

    [Required]
    public DateTime? Created { get; set; }
}

    [Table("Keys")]
public class Key
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Version { get; set; }

    [Required]
    public DateTime? Created { get; set; }
}

    [Table("Tasks")]
public class Task
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Version { get; set; }

    [Required]
    public DateTime? Created { get; set; }
}

Upvotes: 0

Views: 95

Answers (1)

ajliptak
ajliptak

Reputation: 429

Try adding Foreign Keys to your object and making those required instead of making the navigation property required. Like so:

[Table("Tickets")]
public class Ticket
{
    [Key]
    public int Id { get; set; }

    public DateTime? Created { get; set; }

    [Required]
    public int ViewId {get; set; }

    [ForeignKey("ViewId")]
    public View View{ get; set; }

    [Required]
    public int KeyId {get; set; }

    [ForeignKey("KeyId")]
    public Key Key { get; set; }

    public Task Task { get; set; }

}

Upvotes: 1

Related Questions