abpframework / abp

Open Source Web Application Framework for ASP.NET Core. Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET and the ASP.NET Core platforms. Provides the fundamental infrastructure, production-ready startup templates, application modules, UI themes, tooling, guides and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.31k stars 3.32k forks source link

Update One Column in Entity issue #3621

Closed atak946 closed 4 years ago

atak946 commented 4 years ago

Hi everyone,

i'm using nameSpace.table.update method but i have problem.

im updating one column but all column's updating to null,

Example Table Columns:

Example Data:

Id = 1, Name = Murat, Surname = X, BornDate = 1995/26/06, Status = 1

nameSpace.table.update(1, { surname: "ATAK" }).done(r=>{console.log(r);});

After Update Data Result

Id = 1, Name = NULL, Surname = ATAK, BornDate = NULL, Status = NULL

why update function set NULL to all columns?

I just want to update one column, how can I do this?

Best Regards

realLiangshiwei commented 4 years ago

Hi @atak946 You should write partially updated code in your business code. This has nothing to do with abp.

atak946 commented 4 years ago

Hi @atak946 You should write partially updated code in your business code. This has nothing to do with abp. @liangshiw

So when is the nameSpace.update function used?

I did not understand the meaning of this function

when update relational table, this function setted null all relationed id columns but i sent it all columns with filled relation id.

Add Columns to example table:

My Data Before Request:

Id : 1, 
Name: "Murat", 
Surname : "X", 
BornDate :"1995/06/26", 
Status : 1, 
ExampleId = 123, 
tblExample = {FILLED WITH PROPERTIES}

Example Request Data:

var requestData = {id : 1, name: "Murat", surname : "ATAK", bornDate :"1995/06/26", status : 1, exampleId : 123};

nameSpace.table.update(1, requestData);

Result of data:

Id : 1, 
Name: "Murat", 
Surname : "ATAK", 
BornDate :"1995/06/26",
Status : 1, 
ExampleId = NULL, 
tblExample = NULL
realLiangshiwei commented 4 years ago

You should check the code of your application service update method. If you use the curd application service base class, you can override the base class method.

atak946 commented 4 years ago

@liangshiw yes i can override but i need a general fix. the override solution is the last way for us. thank you.

@maliming are you have any idea?

realLiangshiwei commented 4 years ago

I don’t think ABP needs to change.I tested your use case and it has no problems.

Entities:

public class Qa : Entity<int>
{
     public string Name { get; set; }

     public int? QaItemId { get; set; }

     public QaItem QaItem { get; set; }
}

public class QaItem: Entity<int>
{
     public string Name { get; set; }
}

Application Services:

public class TestAppService : CrudAppService<Qa,QaDto, int, PagedAndSortedResultRequestDto, QaDto, QaDto>, ITestAppService
{
   public TestAppService(IRepository<Qa, int> repository) : base(repository)
   {
   }
 }

And test result:

image

atak946 commented 4 years ago

@liangshiw yes, I got a successful result on swagger, but I still have the same problem via javascript function. can you try this?

realLiangshiwei commented 4 years ago

@atak946 image

atak946 commented 4 years ago

@liangshiw

I get successful results with fiddler, but my relational columns with javascript are null. you can see the examples in the images.

I use the same request model in fiddler and javascript

I need to understand the difference between the two I can't solve the problem

The records that I mentioned relationally are available in the tables. I checked them all and got them from the tables

Javascript Test: JSON Data JSONDATA

Javascript Test: Update Result: RESPONSE

Fiddler Test: Json Data: FİDDLER

Fiddler Test: Update Result: FİDDLER RESPONSE

var jsondata = {
  "equipmentNo": "string",
  "meterSerialNo": "string",
  "meterTypeId": "374e5de5-e80d-e630-d24b-39f3e0144161",
  "meterBrand": "string",
  "meterStyle": "string",
  "productionDate": "2020-04-16T08:37:52.445Z",
  "brandDate": "2020-04-16T08:37:52.445Z",
  "voltage": 0,
  "amperage": 0,
  "impulse": 0,
  "location": "string",
  "totalIndex": 0,
  "t1": 0,
  "t2": 0,
  "t3": 0,
  "t4": 0,
  "demand": 0,
  "positiveReactiveInductive": 0,
  "negativeReactiveCapacitive": 0,
  "pR_TotalIndex": 0,
  "pR_T1": 0,
  "pR_T2": 0,
  "pR_T3": 0,
  "pR_T4": 0,
  "procedurePhraseId": "1f8db326-1b47-455e-82bc-9deb98f2b8bd",
  "subscriberTitle": "string",
  "adress": "string",
  "meterRevellingDate": "2020-04-16T08:37:52.445Z",
  "meterRevellingReasonId": "28ed5b10-26b5-4cfe-ba1a-b38a937d5de7",
  "dismantledStaff": "string",
  "reportSerial": "string",
  "reportSerialNo": "string",
  "readType": 1,
  "isCompleted": true,
  "isActive": true,
  "isDeleted": true,
  "workOrderDetailId": "15c7e957-30c4-dacb-8974-39f3fa4044bb",
  "tblMeterType": null,
  "tblProcedurePhrase": null,
  "tblMeterRevellingReason": null,
  "tblWorkOrderDetails": null
};

sayacAyarServisi.workOrder.update(Model.Id, jsondata).done(function (r) {
    console.log(r);
    abp.notify.success("Akış başarıyla tamamlandı ve kapatıldı");
}).fail(function () {
    abp.notify.error("Birşeyler ters gitti lütfen daha sonra tekrar deneyin.");
});
realLiangshiwei commented 4 years ago

Please use the CLI to reproduce, and then give me the repository

atak946 commented 4 years ago

@liangshiw

i'll upload tonight,

As I tested with jquery ajax, only 1 column is going to be null, as most of the problem is solved. When I try with different browsers, only 1 property in the mozilla goes null and there is a problem like chrome in the opera.

I have to identify the problem of the remaining 1 property being null.

$.ajax({
    url: "/api/app/workOrder/338addbf-76ea-dc48-5d8e-39f400498119",
    data: JSON.stringify(jsondata),
    contentType: "application/json",
    dataType: "json",
    type: "PUT",
    success: (r) => {
      console.log(r);
    }
});

JQUERY AJAX

atak946 commented 4 years ago

@liangshiw

not stable :(

aaa

realLiangshiwei commented 4 years ago

Can you give me the repository?

atak946 commented 4 years ago

Can you give me the repository?

https://github.com/atak946/xrepo

if the column is full it empties, if it is empty it fills. it does this only in relational columns

realLiangshiwei commented 4 years ago

@atak946 I mean you use CLI to create a simple project to reproduce the issue.

cotur commented 4 years ago

@atak946

@liangshiw

not stable :(

aaa

Hi @atak946,

With that example, you are using the Update but in your CustomAdvancedCrud there is a method that named UpdateRow and you wrote a different bussines logic in that code but you don't use it. Maybe you need to just use UpdateRow method for your own CustomAdvancedCrud or override the Update.

Also in your code you did not implement the UpdateRow in your ICustomAdvancedCrud

Also I could not run your repository, DbMigrator is also crashed.

So basically it is not related to ABP. The CrudAppService and AutoMagically javascript endpoints are solid stable. The problem is in your code. I suggest you to run in debug mode and watch everyline what is going on? You'll caught the bug.

atak946 commented 4 years ago

@atak946

@liangshiw not stable :( aaa

Hi @atak946,

With that example, you are using the Update but in your CustomAdvancedCrud there is a method that named UpdateRow and you wrote a different bussines logic in that code but you don't use it. Maybe you need to just use UpdateRow method for your own CustomAdvancedCrud or override the Update.

Also in your code you did not implement the UpdateRow in your ICustomAdvancedCrud

Also I could not run your repository, DbMigrator is also crashed.

So basically it is not related to ABP. The CrudAppService and AutoMagically javascript endpoints are solid stable. The problem is in your code. I suggest you to run in debug mode and watch everyline what is going on? You'll caught the bug.

No, updaterow is only different test method not main method. i already have this error. You will remove updaterow. it's not have any dependency

im busy now, i m have this error in clean project created by cli and not have custom crudappservice. i'll upload wait for it.

And this error fired after version update 2.0 to 2.5

atak946 commented 4 years ago

@atak946

@liangshiw not stable :( aaa

Hi @atak946,

With that example, you are using the Update but in your CustomAdvancedCrud there is a method that named UpdateRow and you wrote a different bussines logic in that code but you don't use it. Maybe you need to just use UpdateRow method for your own CustomAdvancedCrud or override the Update.

Also in your code you did not implement the UpdateRow in your ICustomAdvancedCrud

Also I could not run your repository, DbMigrator is also crashed.

So basically it is not related to ABP. The CrudAppService and AutoMagically javascript endpoints are solid stable. The problem is in your code. I suggest you to run in debug mode and watch everyline what is going on? You'll caught the bug.

İngilizcem yetmiyor artık Ahmet bey o updaterow metodunu da denemek için ekledim bu testi yapmamı da liang bey söyledi yukarıda okuyabilirsiniz. sorunla uzaktan yakından ilgisi yok bu sorun 2.0 versiyonundan 2.5 versiyonuna yükseltme yaptıktan sonra çıktı.

CustomCrudAppService ile de ilgisi yok onu kaldırınca da sorun devam ediyor. Müsait olamadim müsait olunca cli ile oluşturulmuş boş projeyi de yükleyeceğim bu konuyu anlamadan kapatmanız da yanlış olmuş.

Ek olarak bu Proje de aktif çalışan bir proje yani önceden beri olan bir hata değil.

Updaterow metodunu da bu sorun çıktıktan sonra denemek için ekledim.

Benim asıl sorunum update fonksiyonunun relation id kolonlarını boş ise doldurması dolu ise boşaltması gönderdiğiniz değerin hiç bir önemi olmadan bunu yapıyor . Umarım anlatabilmişimdir.

@cotur

cotur commented 4 years ago

@atak946 So I reopened it to inspect more. Please mention me when you create the test project with cli.

cotur commented 4 years ago

Hi @atak946,

I've created an example application to explain detailed.

Id = 1, Name = Murat, Surname = X, BornDate = 1995/26/06, Status = 1

nameSpace.table.update(1, { surname: "ATAK" }).done(r=>{console.log(r);});


**After Update Data Result**

Id = 1, Name = NULL, Surname = ATAK, BornDate = NULL, Status = NULL



why update function set NULL to all columns?

I just want to update one column, how can I do this?

You specified your problem here, you want to update one property of an entity, but when you use CrudAppService it will update only what you sent and removes others. It is about the Object to Object Mapping.

I'll give you solution step by step.

I've created app and I have an entity that named Contact

As you said, when I send some data to update it will removes others because there is no good mapping in my project yet. resim

It is occurs because the UpdateAsync do mapping from the input data to the orginal entity. If you do not change AutoMapper settings, it will maps what you sent.

So let's change some settings.

resim

I just added that code to the AutoMapper settings. It will ignores the null variables.

So the result is.

resim

It looks like the problem is fixed!

BUT IMPORTANT!

It is occurs a problem, "What will happen when you want to update a property to NULL", so it is gonna be impossible with previous solution.

You should look at the AutoMapper settings documentation. You'll find the best solition for your implementation. Here is a link for you: AutoMapper Documentation

As I said before, it is not related to the ABP Framework.

atak946 commented 4 years ago

Hi, @cotur

Thanks to @liangshiw I understood the map problem you mentioned and I tried to send all the properties.

I want to draw your attention to one more point, this problem happens if there is more than one relation id in the table (i have 4 column). I noticed that I did not experience this problem in other tables in my project.

but this time I came across another problem, I tried to convey and share visuals but I guess it is a problem I cannot explain.

this is not a normal problem, why should it succeed when it first executes the same request and fails when it triggers again later. It's hard to explain.

My problem is that although I send this field full, it will be saved as empty.

Please read this comment. https://github.com/abpframework/abp/issues/3621#issuecomment-615094577

after readed the comment, please look at the gif image (bottom of the next comment)

Thank you for your interest.

cotur commented 4 years ago

I tried this issue at repository that shared with us by you.

The problem is wrong DTO implementation.

Experimental Solution: Atak-Problem-Solved

The Update_X_Dto should contains the properties what we want to update. But your Update_X_Dto contains several Navigation Properties.

When you call UpdateAsync method, the Navigation Properties are creating with null then it occurs wrong mapping. While the result is creating, the AutoMapper should override the IDs' and you don't see those in your response.

As a result, we should follow Best Practises. :)