Entity Framework: .Add & .SaveChanges() is not adding entity to database - sql

When I am adding an entry
var objectEntity = new ObjectStaging();
objectEntity .CreatedBy = ClaimsPrincipal.Current.Identity.Name;
objectEntity .ModifiedBy = ClaimsPrincipal.Current.Identity.Name;
objectEntity .Set(ObjectInfo);
database.ObjectStaging.Add(objectEntity);
database.SaveChanges();
For some reason, my objectEntity is not being added to my database given the following code. When using the debugger, it moves through database.ObjectStaging.Add(objectEntity); but does not continue after calling SaveChanges(). Is there a way to know why it is failing to add the entry to the database?
Exception Thrown:
Exception thrown:
'System.Data.Entity.Validation.DbEntityValidationException' in
VCC.BrokerPortal.DAO.dll Validation failed for one or more entities.
See 'EntityValidationErrors' property for more details.
Is there a way to know what specifically did not validate?
Also, I tested the state of the entity using the following lines of code,
database.ObjectStaging.Add(objectEntity);
var state= brokerPortalDB.Entry(objectEntity).State;
state currently shows the value of 'added'.

Thank you!
I ended up looking into the exception thrown and it appears it was related to one of the properties not having proper validation. In this instance I had a [MaxLength] attribute assigned to a field and I was trying to add a value longer than that length allowed.

Related

How can I use Format Arguments in BusinessException?

I have noticed the abp localization provide a Format Arguments mechanism to help generate realtime local string by this way, and I want to know how can I do the same thing in calling a BusinessException while all its overloads are not suitable for this purpose.
Please see the documentation: https://docs.abp.io/en/abp/latest/Exception-Handling#exception-localization
It is possible to set an exception code and data related to the exception. Then ABP automatically localizes the exception message by also using the data arguments you've provided.
Example exception:
throw new BusinessException("App:010046")
.WithData("UserName", "john");
And the related localization entry in the json file:
"App:010046": "Username should be unique. '{UserName}' is already taken!"
It is not using {0}, {1}... but using parameter names instead.

Send exception for UNIQUE constraint to UI in .NET core

When a unique constraint exception occurs, how do I message the UI in .NET Core; I want to return JSON, not MVC/Razor approach.
I think you have been looking at my article Catching Bad Data in Entity Framework. In there I describe a way to catch a SQL error and turn it into a validation error for EF Core.
UPDATE
In answer to your follow on questions I can point you to the code associated with the book I am writing, Entity Framework Core in Action. In this I built a method called SaveChangesSqlCheck, which contains the code to check for sql errors. You would use this method instead of calling SaveChanges, and it will return a ValidationResult.
My book has associated git repository where I have unit tests for just about everything I show in the book. Below are links to a unit test to see how you call SaveChangesSqlCheck, and then the SaveChangesSqlCheck code itself.
Unit test: https://github.com/JonPSmith/EfCoreInAction/blob/Chapter10/Test/UnitTests/DataLayer/Ch10_CatchSqlError.cs#L59-L89
The SaveChangesSqlCheck code: https://github.com/JonPSmith/EfCoreInAction/blob/Chapter10/DataLayer/EfCode/SaveChangesSqlCheck.cs
The method that catches the Unique error: https://github.com/JonPSmith/EfCoreInAction/blob/Chapter10/DataLayer/EfCode/SqlErrorFormatters.cs
Note: you need to format the unique constraint name in a special way - see https://github.com/JonPSmith/EfCoreInAction/blob/Chapter10/Test/Chapter10Listings/EfCode/Configuration/MyUniqueConfig.cs for an example.
If you plan to use the code shown in the article then all you need to do is use JsonConvert.SerializeObject(errors) to turn that into json. I have included some code so you can see what the json output would look like.
var error = new ValidationResult("error message");
var jsonList = JsonConvert.SerializeObject(error,
new JsonSerializerSettings { Formatting = Newtonsoft.Json.Formatting.Indented });
The json output of this would be
{
"MemberNames": [],
"ErrorMessage": "error message"
}
I hope that helps.

ssis Package validation error ole db source failed

I am getting the following error when I try and run my package. I am new to ssis. Any suggestions. Tahnks
===================================
Package Validation Error (Package Validation Error)
===================================
Error at Data Flow Task [SSIS.Pipeline]: "OLE DB Source" failed validation and returned validation status "VS_NEEDSNEWMETADATA".
Error at Data Flow Task [SSIS.Pipeline]: One or more component failed validation.
Error at Data Flow Task: There were errors during task validation.
(Microsoft.DataTransformationServices.VsIntegration)
Program Location:
at Microsoft.DataTransformationServices.Project.DataTransformationsPackageDebugger.ValidateAndRunDebugger(Int32 flags, IOutputWindow outputWindow, DataTransformationsProjectConfigurationOptions options)
at Microsoft.DataTransformationServices.Project.DataTransformationsProjectDebugger.LaunchDtsPackage(Int32 launchOptions, ProjectItem startupProjItem, DataTransformationsProjectConfigurationOptions options)
at Microsoft.DataTransformationServices.Project.DataTransformationsProjectDebugger.LaunchActivePackage(Int32 launchOptions)
at Microsoft.DataTransformationServices.Project.DataTransformationsProjectDebugger.LaunchDtsPackage(Int32 launchOptions, DataTransformationsProjectConfigurationOptions options)
at Microsoft.DataTransformationServices.Project.DataTransformationsProjectDebugger.Launch(Int32 launchOptions, DataTransformationsProjectConfigurationOptions options)
VS_NEEDSNEWMETADATA shows up when the underlying data behind one of the tasks changes. The fastest solution will probably be to just delete and re-create each element which is throwing an error.
How about disabling validation checks?
Like if you right click on source or destination component and select properties then you will have the property named validateExternalMetadata put that as false and try.
This Solution is working for me.
This normally occurs if there has been a change to your schema, not to stress, just double click on your input and output and it should resolve itself
Make sure your connection is valid. If you are using dynamic connections, then try to set the option "delay validation" = true on the package or dataflow.
In my case destination table structure was not matching with matadata in OLEDB component. I added the missing column which i forgot to add and after that it was fixed.
After researching a bit (check to extract your own conclusions: this and this one), I think I've found a nice workaround for when the problem with the metadata comes from a Ole DB object, but only for a very specific case.
The thing is that when you change your columns names / remove columns / add columns, you can't do anything but update the metadata.
However, if you use a SQL query to retrieve the data from the object, in the case that you don't need to update the query itself, you won't need to update the metadata if the query still can ask for what it wants. Basically, if the query is still valid.
I've tried it within my own ETL, and changed an Ole DB object which was reading the data from an Excel file, targeting one sheet and then I had all the columns selected in the tab.
Changing it for an SQL query to retrieve the full sheet like:
SELECT * FROM ['Sheet_Name$']
Solved completely the case for me, even introducing files with different metadata in headers.

IQueryable serialization (web api)

Why isn't this working?:
var surveys = db.Surveys.Where(s => s.Author.UserId == user.UserId);
return from survey in surveys
select new
{
surveyId = survey.SurveyId,
title = survey.Title
};
And this, with a minor change, is?:
var surveys = db.Surveys.Where(s => s.Author == user);
return from survey in surveys
select new
{
surveyId = survey.SurveyId,
title = survey.Title
};
It throws a serialization error
The 'ObjectContent`1' type failed to serialize the response body for content type
'application/xml; charset=utf-8'. (...)
I'm fine with solving it that way, but I have the same error here (below), and can't solve it the same way:
var surveys = db.Surveys.Where(s => s.AnswerableBy(user));
I ran into this issue recently, in my case the problem was that I had circular references created by the Entity Framework - Model First (Company -> Employee -> Company).
I resolved it by simply creating a view model object that had only the properties I needed.
As per the section 'Handling Circular Object References' here on the Microsoft ASP.NET Web API website, add the following lines of code to the Register method of your WebAPIConfig.cs file (should be in the App_Start folder of your project).
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
There are separate instructions on that page for dealing with XML parsing.
The exception you are seeing is a general exception, which can be caused by any number of factors. Check the InnerException property of the serialization exception to find out what exactly caused the serialization to fail.
You are using an anonymous object. Make it strongly typed and the serialization will work.
At the end this has to do with Linq to Entities vs Linq to Objects.
Some LINQ queries can not be translated into SQL (like using a method: someCollection.Where(p => p.SomeMethod() == ...)). So they must be translated to memory first (someCollection.ToList().Where...)
I was having the same problem. In my case the error was caused by the relation between tables created in my Dbml file. Once I removed the relation from the DBML file, it worked. I think Database relations can't be serialized.

Ninject: More than one matching bindings are available

I have a dependency with parameters constructor. When I call the action more than 1x, it show this error:
Error activating IValidationPurchaseService
More than one matching bindings are available.
Activation path:
1) Request for IValidationPurchaseService
Suggestions:
1) Ensure that you have defined a binding for IValidationPurchaseService only once.
public ActionResult Detalhes(string regionUrl, string discountUrl, DetalhesModel detalhesModel)
{
var validationPurchaseDTO = new ValidationPurchaseDTO {...}
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
...
}
I'm not sure what are you trying to achieve by the code you cited. The error is raised because you bind the same service more than once, so when you are trying to resolve it it can't choose one (identical) binding over another. This is not how DI Container is supposed to be operated. In your example you are not getting advantage of your DI at all. You can replace your code:
KernelFactory.Kernel.Bind<IValidationPurchaseService>().To<ValidationPurchaseService>()
.WithConstructorArgument("validationPurchaseDTO", validationPurchaseDTO)
.WithConstructorArgument("confirmPayment", true);
this.ValidationPurchaseService = KernelFactory.Kernel.Get<IValidationPurchaseService>();
With this:
this.ValidationPurchaseService = new ValidationPurchaseService(validationPurchaseDTO:validationPurchaseDTO, confirmPayment:true)
If you could explain what you are trying to achieve by using ninject in this scenario the community will be able to assist further.
Your KernelFactory probably returns the same kernel (singleton) on each successive call to the controller. Which is why you add a similar binding every time you hit the URL that activates this controller. So it probably works the first time and starts failing after the second time.