Comments (11)
Of note, when I take the value conversion away, the exception does seem to allude to the NRT suitability of the property mapping in question. Again... with the NRT, does not seem to consistently verify the actual value post-conversion, meaning the breakpoint does not land there.
from efcore.pg.
Further seems to be throwing from efcore BatchExecutor
, as a function of the Npgsql
being adapted in. Seems like an odd place to be encountering this issue, except perhaps as a function of pg integration.
from efcore.pg.
It is trying to do an INSERT
first followed by an UPDATE
? The infamouse pg upsert pattern, IIRC, from Marten
experience, for example.
As a 🧠 experiment, I wondered if possibly the efcore mapping needed help in determining an appropriate upsert default default value. Which IMO renders native database behaviors such as DEFAULT "[]"::JSON
completely and totally irrelevant. I mean what's the point of using those sort of clauses, if the ORM is going to want control over that? At any rate, with this bit here:
o.Property(p => p.Items).HasColumnName("itemsjson").HasColumnType("json").IsRequired().HasDefaultValue(Array.Empty<string>()).HasConversion(new ItemsValueConverter());
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Without seemingly EVER consulting with the model ACTUAL VALUE not even once. IMO should be seeing the conversion happen in both directions but never see the ConvertTo
except for the one initial time.
from efcore.pg.
This all being said, it seems to "work" when I help the mapping use cases. But it is a bit disconcerting that:
- The pattern is not more model centric, consulting with actual property values
- We cannot apparently make certain native database decisions, i.e.
DEFAULT "[]"::JSON
, even in theupdate-insert
i.e.upsert
scenario. What's the point of pg defaults if they would not actually take effect during an insert? Useless, completely worthless IMHO.
Your 🧠 ... Cheers 🍻
from efcore.pg.
Oh my here is the log, seems even worse than that. I do not know how either the Items
or itemsjson
column are being done here. They are apparently being completely ignored, pruned from the query through the ORM.
I never see breakpoints on either the property get or the value conversion ConvertTo
step. Except the first time, observed in passing thinking "interesting" then ever again wondering "concerning", apparently falling back to NRT biased type validation.
2024-08-01 12:02:44.443 EDT [33688] LOG: execute <unnamed>: INSERT INTO efcore_minpro_modeltemplate (id) VALUES ($1) RETURNING itemsjson
2024-08-01 12:02:44.443 EDT [33688] DETAIL: parameters: $1 = '49585949-78b7-44c7-a7b7-7b9551557f14'
Anyone else seeing a problem with this in the log? I get the RETURNING
part, which if I understand that, then does not see a reason to do the subsequent UPDATE
, if that is truly pending. Maybe that happened in a completely other Task
asynchronous worker thread, so my breakpoint in the main program context never lands, who knows 🤷♂️ .
from efcore.pg.
Out of curiosity, I add some trace logging, but those are not logging either, I would half expect them to.
public static string ConvertTo(ICollection<string> items)
{
Trace.WriteLineIf(items is null, $"{nameof(items)} is null");
Trace.WriteLineIf(items is not null, $"{nameof(items)} is not null");
// Intentionally returning empty JSON array here, for sake of minpro example
return "[]";
}
And in the property, along similar lines:
get
{
Trace.WriteLineIf(_items is null, $"{nameof(_items)} value is null");
Trace.WriteLineIf(_items is not null, $"{nameof(_items)} value is not null: Count = {_items.Count}");
return _items ??= [];
// ^^^^^^
}
Neither of which is happening. I do see the property trace, when I debug inspect the model
instance, but that is it.
Which tells me the ORM is never using that value. I'm not sure how that is even possible, unless perhaps a proxy class is being generated. Which from my NHibernate
experience, for example, I know that can be thing, which commonly includes the active database code in the instance.
from efcore.pg.
Vis-a-vis the issue at hand and observations, wanting to know a few things, best I can estimate.
- Are efcore and npgsql adapters making some assumptoins about, taking liberties regarding, underlying model, NRT-ness, and so on. It is our preference, obviously, for the operation to be as model centric as possible, with the efcore repository being a transparent as possible serialization layer.
- Why is it that the mapping seems to require a default spec? Without which fails during (presumably) upsertion, throws an exception, presumably around the NRT question, but that is not clear, and certainly not based on the actual values in play.
- Why is it the mapping and
DbSet<T>
are entirely ignoring, it would seem, bypassing the model property getter; unless, as speculated here, that is happening during anasync
orTask
oriented worker thread. The truly perplexing thing is, we get noTrace
responses.
The implications of which, just trying to understand the whats, hows and why fors, if you will, because that will determine the modes in which we are expected to operate, versus efcore, etc, in order to do the work we want it to do.
For @roji or really anyone with insights around the question.
Will have my minpro updated shortly with the current revelations, observations, introspections, etc.
Thanks for bearing with me, it has been rather educational the idiosyncacies of both efcore as well as npgsql and pg in general.
from efcore.pg.
Summarizing above, besides the NRT default value versus NOT NULL
constraint concerns... The main objection is during the DbSet<T>.Add
, is completely one hundred percent disrespecting the CURRENT OBJECT STATE. It seems to be reaching down to the database layer for its default values whatever those happen to be, and using those. With complete disregard for the model instance we gave it in the first place, whatever however those property values shall have been furnished, calculated, internally defaulted, and so on. The only way we have found to ensure that is not the case, is to walk each of the properties, and ensure we do the corresponding get
. I'm not sure, is there some npgsql or otherwise efcore policy which may be set which does the right thing in this regards? Again, kindly pardoning my ignorance, maybe there are good reasons for why it is doing what it is doing, I do not know. Perhaps educate me in this area.
from efcore.pg.
I think I see what might be happening, but I think the idea of field preference is dangerous.
modelBuilder.UsePropertyAccessMode(PropertyAccessMode.Property);
from efcore.pg.
I'm satisfied I think the property field confusion was the major solution in this area.
Still the NRT (or lack there of), default values portion, could use some clarification. My guess is, the type validation taking liberties with non-NRT produced IL and so forth. Not sure why there also needs ot be a default value specific, when the model furnishes its properties, but whatever.
Cheers 🍻
from efcore.pg.
@mwpowellhtx I've quickly read through this issue and through npgsql/npgsql#5797 - there's a lot going on and I don't quite understand what exactly you're asking, and if you figured it out or have further issues. If you do, can you please post a minimal repro and describe one precise problem you have at a time?
from efcore.pg.
Related Issues (20)
- Unable to Fetch Data from Stored Procedure with Cursor as return type and getting required column id was not present in the results of a "FromSql" operation.
- Implement migration locking
- Replace type reloading mechanism with the new EF migration extensibility mechanism
- DateOnly - en_GB date flipped from October to April. HOT 2
- LTree column type doens worked with migration
- Errors on mapping enum types to SQL and storing into database
- Is there way to translate EF Core query to WITH Queries (Common Table Expressions) ? HOT 3
- Select or filter Length of string contained in JsonB column
- Value Conversion Not Applied when using DbFunction in EF Core HOT 1
- ExecuteDelete cloud not betranslated but querying can HOT 3
- Warning: Found conflicts between different versions of "Microsoft.EntityFrameworkCore.Relational" that could not be resolved on Microsoft.EntityFrameworkCore.Relational 8.0.4 and 8.0.7 HOT 4
- Received backend message ParseComplete while expecting BindCompleteMessage using pgcat pooler
- Guidance for NodaTime postgres data types HOT 3
- v8.0.4 - First async query to run fails HOT 1
- SRID is ignored when writing NetTopologySuite Geometry properties inside objects mapped with ToJson()
- Is Npgsql.EntityFrameworkCore.PostgreSQL stop updating? HOT 2
- Issue Configuring `EnableDynamicJson()` on Data Source with a Multi-Tenant API Leveraging Postgres Row-Level Security
- EF not persisting updating value converted collections to JSON HOT 6
- How to handle Enum in .net core with entity framework USING PostgreSQL HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from efcore.pg.