locked
Why is my code creating a new ResourceType entity? RRS feed

  • Question

  • I'm using Code First.
    I have an entity named ResourceItem. I'm creating new ResourceItems, from data I read from another database.
    Each ResourceItem can have a ResourceType. But when I try to set an existing ResourceType to a ResourceItem, it instead creates a brand new ResourceType in my table. Why is it creating a new ResourceType?
    //Code First entities
    public class ResourceItem
    {
    		public int ResourceItemId { get; set; }
    
    		public string NameTitle { get; set; }
    		public string Description { get; set; }
    		public string OwnerOrg { get; set; }
    		public string RefCitation { get; set; }
    		public string AuthorsText { get; set; }
    		public string Url { get; set; }
    		public string Location { get; set; }       
    
    		//[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
    		public DateTime? StartDate { get; set; }   
    
    		//[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
    		public DateTime? EndDate { get; set; }     
    		public DateTime? PublishStartDate { get; set; }
    		public DateTime? PublishEndDate { get; set; }
    		public DateTime CreatedDate { get; set; }  
    		public string Keywords { get; set; }
    
    		public bool Active { get; set; }
    
    		//many to one
    		public virtual ResourceType ResourceType { get; set; }
    		public virtual WebsiteSection WebsiteSection { get; set; }
    
    		//many to many
    		public virtual ICollection<Author> Authors { get; set; }
    		public virtual ICollection<WebsiteSubscriber> WebsiteSubscribers { get; set; }
    
    		public ResourceItem()
    		{
    				Authors = new HashSet<Author>();
    				WebsiteSubscribers = new HashSet<WebsiteSubscriber>();
    		}
    }
        
    
     public class ResourceType
     {
    		 public int ResourceTypeId { get; set; }
    		 public string Description { get; set; }
    
    		 public virtual ICollection<ResourceItem> ResourceItems { get; set; }
    
    		 public ResourceType()
    		 {
    				 ResourceItems = new HashSet<ResourceItem>();
    		 }
    }
        
        
        
    //the portion of code that creates a new ResourceItem, reading in the data from a SqlDataReader
    
    using (var db = new ResourceLibraryContext())
    {
    		while (reader.Read())
    		{
    				ResourceItem resource = new ResourceItem();
    				resource = AddResourceItem(
    							 reader["NameTitle"].ToString(),
    							 reader["OwnerOrg"].ToString(),
    							 reader["AuthorsText"].ToString(),
    
    							 reader["Description"].ToString(),
    							 reader["RefCitation"].ToString(),
    							 reader["Url"].ToString(),
    
    							 reader["Location"].ToString(),
    							 reader["Keywords"].ToString(),
    							 reader["StartDate"].ToString(),
    
    							 reader["EndDate"].ToString(),
    							 reader["PublishEndDate"].ToString(),
    							 reader["PublishStartDate"].ToString(),
    							 reader["ResourceType_ResourceTypeId"].ToString()
    				);
    
    				db.ResourceItems.Add(resource);
    		}
    
    		int recordsaffected = db.SaveChanges();
    }
    
    
    //the method where my problem occurs - why does this create a brand new ResourceType?
    
    private ResourceItem AddResourceItem(
                        string nametitle,
                        string ownerorg,
                        string authorstext,
    
                        string description,
                        string refcitation,
                        string url,
    
                        string location,
                        string keywords,
                        string startdate,
    
                        string enddate,
                        string publishenddate,
                        string publishstartdate,
                        string resourceTypeId
         )
            {
                ResourceItem resource = new ResourceItem();
    
                using (var db = new ResourceLibraryContext())
                {
    								resource.NameTitle = nametitle;
    								resource.Description = description;
    								resource.OwnerOrg = ownerorg;
    								resource.RefCitation = refcitation;
    								resource.AuthorsText = authorstext;
    								resource.Url = url;
    								resource.Location = location;
    								resource.CreatedDate = DateTime.Today;
    								resource.StartDate = DateTime.Today;
    								resource.PublishStartDate = DateTime.Today;
    								resource.Keywords = keywords;
    								resource.Active = true;
    
    								//set the resource type
    								int typeId = ConvertResourceTypeId(resourceTypeId);
    								var resourceType = db.ResourceTypes.FirstOrDefault(res => res.ResourceTypeId == typeId);
    
    								//BUG - THE FOLLOWING LINE CAUSES A BRANG NEW RESOURCE TYPE TO BE CREATED - WHY?
    								resource.ResourceType = resourceType;
    
    
                    return resource;
                }
            }
    



    Wednesday, January 25, 2012 4:52 PM

Answers

  • Hi hapax,

    According to your description, it is very strange. I think you should call savechanges in every "using" block.

    You can test the simple scenario to test:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    using System.ComponentModel.DataAnnotations;
    
    namespace ManytoOne
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var db= new MyContext())
                {
                    /*add one records to database*/
                    //var type = new ResourceType { ResourceTypeId=1, Description="TypeA" };
                    //db.ResouceTypes.Add(type);
                    //db.SaveChanges();
                    /* create a new item with existed type*/
                    var item = new ResourceItem {  ResourceItemId=1, Active=true, Keywords="test", ResourceType= db.ResouceTypes.FirstOrDefault(t=>t.ResourceTypeId==1)};
                    db.ResouceItems.Add(item);// note: we just need to add item to context, ef will automatically set each relationships
                    db.SaveChanges();
                }
            }
        }
        public class ResourceItem
        {
        [Key]
            public int ResourceItemId { get; set; }
            public string Keywords { get; set; }
            public bool Active { get; set; }
            public virtual ResourceType ResourceType { get; set; }
        }
    
    
        public class ResourceType
        {
            [Key]
            public int ResourceTypeId { get; set; }
            public string Description { get; set; }
            public virtual ICollection<ResourceItem> ResourceItems { get; set; }
            public ResourceType()
            {
                ResourceItems = new HashSet<ResourceItem>();
            }
        }
        public class MyContext:DbContext
        {
            public DbSet<ResourceType> ResouceTypes { get; set; }
            public DbSet<ResourceItem> ResouceItems { get; set; }
        }
    }
    
    

    Have a nice day.

     


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Alan_chen Thursday, February 2, 2012 6:05 AM
    Monday, January 30, 2012 2:41 AM