0

Exception :

System.InvalidOperationException: The operation failed: The relationship could not 
be changed because one or more of the foreign-key properties is non-nullable. When 
a change is made to a relationship, the related foreign-key property is set to a 
null value. If the foreign-key does not support null values, a new relationship 
must be defined, the foreign-key property must be assigned another non-null value, 
or the unrelated object must be deleted.

I have seen some solutions for the above issue as shown below.But none of them worked for me :( May be due to those solutions are for the EF 4.x versions.My app's EF version is 6.x.

Solution 1 and Solution 2

 [Table("IpTaxMapLots")]
    public class TaxMapLot : FullAuditedEntity
    {
        public const int MaxLength = 50;

        [Required]
        [MaxLength(MaxLength)]
        public virtual string District { get; set; }

        [ForeignKey("PropertyId")]
        public virtual Property Property { get; set; }
        public virtual int PropertyId { get; set; }
    }

 [Table("IpProperties")]
    public class Property : FullAuditedEntity
    {
        public const int MaxLength = 50;

        [MaxLength(MaxLength)]
        public virtual string Dist { get; set; }

        public virtual ICollection<TaxMapLot> TaxMapLots { get; set; }
    }

public async Task<int?> EditPropertyAsync(CreateOrEditPropertyInput input)
        {
            var property = await _propertyRepository.FirstOrDefaultAsync(p => p.Id == input.Property.Id);
            input.Property.MapTo(property);

            await _propertyRepository.UpdateAsync(property);//issue is here
            return input.Property.Id;
        }


public class CreateOrEditPropertyInput : IInputDto
    {
        [Required]
        public PropertyEditDto Property { get; set; }
    }

[AutoMap(typeof(Property))]
    public class PropertyEditDto
    {
        public const int MaxLength = 50;
        public int? Id { get; set; }

        [MaxLength(MaxLength)]
        public string Dist { get; set; }

        public List<TaxMapLotDto> TaxMapLots { get; set; }

    }

As I mentioned above Where I have used repositories on my app.So could you tell me how to sort out above issue ? Thanks.

Note : I can add records to the db.But problem occurs when I try to do the update.

Image representation :

1 : M

img1

This comes when you click the Lot Info Button above.

enter image description here

Note : There are 2 tables.One is Properties and other is TaxMapLots.The relationship is 1 : M. User can add/edit or delete records on the TaxMapLot form.

Update : Actually I can Add a record.The problem occurs when I try to edit the record.

This works fine (CreatePropertyAsync): It adds record to both the table (Properties and TaxMapLots).The problem is on the Edit method as shown above.

public async Task<int> CreatePropertyAsync(CreateOrEditPropertyInput input)
        {
            var property = input.Property.MapTo<Property>();
            var propertyId = await _propertyRepository.InsertAndGetIdAsync(property);
            return propertyId;
        }
Community
  • 1
  • 1
Sampath
  • 63,341
  • 64
  • 307
  • 441

2 Answers2

0

This happens because previous related TaxMapLot are being removed from the TaxMapLots collection when you are mapping dto to entity, as your dto contains full graph.

EF thinks your collection items are new ones and previous are being removed so theirs PropertyIds becomes null. You need to handle updating TaxMapLot by yourself instead of letting mapper do it for you.

tede24
  • 2,304
  • 11
  • 14
  • Could you explain your solution by using some code samples ? Thanks. – Sampath Feb 13 '16 at 16:49
  • Yes, but first you should add some details to your question: what do you want to happen with collection members when you update? You don't add details of expected update behavior in your question – tede24 Feb 13 '16 at 17:29
  • There are 2 tables.One is `Properties` and other is `TaxMapLots`.The relationship is 1 : M. User can `add/edit or delete` records on the `TaxMapLot` form. – Sampath Feb 13 '16 at 17:43
0

Make foreign key PropertyId nullable in both, datatabase table IpTaxMapLots and TaxMapLot entity:

public virtual int? PropertyId { get; set; }

Of course you need to think if for your business make sense to have a TaxMapLot without a Property.

E-Bat
  • 4,792
  • 1
  • 33
  • 58
  • Can't do that.It must have `propertId` on the `Tax` table.Otherwise need to delete it.But I don't know how to delete it :( Do you know ? Thanks. – Sampath Feb 13 '16 at 19:31
  • To delete, just set cascade to Delete in table IpTaxMapLots for the relation with IpProperties table. – E-Bat Feb 13 '16 at 19:42
  • Actually it is there by default.`.PrimaryKey(t => t.Id) .ForeignKey("dbo.IpProperties", t => t.PropertyId, cascadeDelete: true) .Index(t => t.PropertyId);` – Sampath Feb 13 '16 at 19:46
  • So you are not deleting, for some reason you are just blanking the property. What is this call doing?----> await _propertyRepository.UpdateAsync(property); – E-Bat Feb 13 '16 at 19:53
  • I need to edit and save the changes here.No need to delete.Thanks. – Sampath Feb 13 '16 at 19:58
  • Yes I get that, what is the method UpdateAsync doing internally? – E-Bat Feb 13 '16 at 20:02
  • Here it is : http://aspnetboilerplate.com/Pages/Documents/Repositories#DocUpdateEntity – Sampath Feb 13 '16 at 20:07