C
C#2y ago
İrşat

EF sets a property out of nowhere [Solved] [Answered]

public int RepliesLength { get; set; } = 0;
public int RepliesCount { get; set; } = 0;

public CommentDtoRead_2(ICollection<VoteDto>? Votes, ICollection<ReplyDtoRead_1>? Replies)
{
if(Replies != null && Replies.Count > 0) {
this.RepliesLength = Replies.Count(r => r.DeletedStatus!.Body == "Default");
this.RepliesCount = Replies.Count(r => r.DeletedStatus!.Body == "Default");
}
}
public int RepliesLength { get; set; } = 0;
public int RepliesCount { get; set; } = 0;

public CommentDtoRead_2(ICollection<VoteDto>? Votes, ICollection<ReplyDtoRead_1>? Replies)
{
if(Replies != null && Replies.Count > 0) {
this.RepliesLength = Replies.Count(r => r.DeletedStatus!.Body == "Default");
this.RepliesCount = Replies.Count(r => r.DeletedStatus!.Body == "Default");
}
}
I have a model with this constructor. Basically, I get the amount of replies which are not deleted through Count. Total is 5 and 3 of them are not deleted. Literally the same codes. But at the end, RepliesCount returns 5 and RepliesLength returns 3. RepliesLength can have any name. But when I use the name "RepliesCount", it fetches all the replies. I used breakpoints to see where it comes from since I didn't reference to it anywhere. It starts filling properties, assigns 3 to both, as one would expect. But after filling others properties, for some reason it jumps to setter and assigns 5 to RepliesCount. My theory; EF can fill the Replies if I want. Perhaps if I write the "Replies" then add "Count" at the end, it automatically runs the Count function and assigns to it? Because I didn't reference it anywhere.
24 Replies
Pobiega
Pobiega2y ago
EF will respect constructors if it can figure out which one to use (names etc match properties), but it can also just set the props directly you might be running into a situation where it does both generally, you either provide a ctor that has matching arguments for all the database-bound fields, or an empty ctor
İrşat
İrşat2y ago
well, i wanted to do some quick calculations inside the constructor of dto so I would have an easy way of using them later. Like in the api controller. I don't want to loop through the comments and give them the number of replies after all i am not sure which one is faster but let me try the same thing with some other list. votes, come here I already have VoteResult. Which is the small calculation of upvotes and downvotes. I will create a property called VoteCount Nope. "voteCount": 0. It should give me 2 sorry it should be VotesCount there is still a chance 😄 LMAO It worked "votesCount": 2, @Pobiega dammit EF. How dare you make me a monkey for 5 hours
Pobiega
Pobiega2y ago
Do you keep these DTOs in your database? at that point, they are not DTOs anymore - they are entities
İrşat
İrşat2y ago
Not database. Api I am not sure if you meant api there
Pobiega
Pobiega2y ago
I meant database. why would EF be invovled with your API at all? EF is used to talk to the database only.
İrşat
İrşat2y ago
You seem like a knowledged person. So I ruled out most of my guesses. Did I understand correctly? Api speaks to database. And I am just calling the api to give me data. I don't have EF in my app. It's for api
Pobiega
Pobiega2y ago
Mhm.. Perhaps its better if you just show the code where you use this? I interpreted your original post as if you thought EF was calling your constructor by itself and/or assigning the props
İrşat
İrşat2y ago
I am approaching home. A couple of things to do, at leadt 30 minutes sadly
Pobiega
Pobiega2y ago
but thats obviously not the case, since this is a DTO
İrşat
İrşat2y ago
No no Dtos are in the api. My api uses ef to speak to database I just created the models I need in my app.
Pobiega
Pobiega2y ago
Sure. Well, get home, do whatever you need, then come back and post the code where you use this DTO this.RepliesCount = ... will call the setter, btw just so you know it obviously shouldn't be sticking a 5 in there, so we'll need to see the full code to figure out why
İrşat
İrşat2y ago
It's an extra property. I fixed it already, sorry I didn't changed the title I don't fetch the replies. I only need its count. Writing the List type property name and adding "Count" to it like "RepliesCount" brings the count of that list, overriding the previously assigned values. It took quite a while to learn that. I simply changed the Count with Length.
Pobiega
Pobiega2y ago
That is not automagic. Are you using some kind of mapping library? Automapper, Mapster?
İrşat
İrşat2y ago
Yes. Obviously there is EF magic. Autonapper
Pobiega
Pobiega2y ago
EF isnt involved, you said so yourself
İrşat
İrşat2y ago
I don't know. But EF is the one that checks the names and assigns stuff
Pobiega
Pobiega2y ago
If your controller/service/handler code is
var data = await dbContext.GetData()...;

var model = _mapper.Map<Dto>(data);
var data = await dbContext.GetData()...;

var model = _mapper.Map<Dto>(data);
then EF never touches your dto at all
You dont need to map the property explicitly, automapper interprets the property name and auto map Projects.Count() to ProjectsCount
found this in a SO comment, and its pretty much what I expected If your model has a Replies prop, and your DTO has a RepliesCount prop, it will autofill Automapper is sneaky, it has a lot of default behaviour that you need to consider
İrşat
İrşat2y ago
So it's automapper magic 😄
Pobiega
Pobiega2y ago
yup!
İrşat
İrşat2y ago
now i can sleep peacifully. Thanks, take care
Pobiega
Pobiega2y ago
I've kinda jumped ship from AutoMapper lately, because of things like this
Accord
Accord2y ago
✅ This post has been marked as answered!
Pobiega
Pobiega2y ago
(we have a bot command to mark questions as closed, /close)
İrşat
İrşat2y ago
I see