C
C#•9mo ago
Timo Martinson

Preparing Models for an API (How to setup relationships)

Hey fellows! I wonder how to set the properties for related models ... Here is my model:
public class Comment(string name, string content)
{
public Guid Id { get; set; } = Guid.NewGuid();

public string Name { get; set; } = name;
public string Content { get; set; } = content;

public DateTime CreatedAt { get; set; } = DateTime.Now;
public DateTime UpdatedAt { get; set; } = DateTime.Now;

public User? User { get; set; }
public Post? Post { get; set; }
}
public class Comment(string name, string content)
{
public Guid Id { get; set; } = Guid.NewGuid();

public string Name { get; set; } = name;
public string Content { get; set; } = content;

public DateTime CreatedAt { get; set; } = DateTime.Now;
public DateTime UpdatedAt { get; set; } = DateTime.Now;

public User? User { get; set; }
public Post? Post { get; set; }
}
Thank you for your help.
101 Replies
Pobiega
Pobiega•9mo ago
This is fine, if you want a fully mutable entity I'd highly recommend adding foreign key properties to the models thou Ie public int UserId ...
Timo Martinson
Timo MartinsonOP•9mo ago
could you explain how to create foreign key props?
Pobiega
Pobiega•9mo ago
Just have it be the same type as your Id prop in the other models
Timo Martinson
Timo MartinsonOP•9mo ago
nice.
namespace Textopia.Models;

public class Comment(string name, string content)
{
public Guid Id { get; set; } = Guid.NewGuid();

public string Name { get; set; } = name;
public string Content { get; set; } = content;

public DateTime CreatedAt { get; set; } = DateTime.Now;
public DateTime UpdatedAt { get; set; } = DateTime.Now;

public User? User { get; set; }
public Guid? UserId { get; set; }

public Post? Post { get; set; }
public Guid? PostId { get; set; }
}
namespace Textopia.Models;

public class Comment(string name, string content)
{
public Guid Id { get; set; } = Guid.NewGuid();

public string Name { get; set; } = name;
public string Content { get; set; } = content;

public DateTime CreatedAt { get; set; } = DateTime.Now;
public DateTime UpdatedAt { get; set; } = DateTime.Now;

public User? User { get; set; }
public Guid? UserId { get; set; }

public Post? Post { get; set; }
public Guid? PostId { get; set; }
}
would this be cool?
Pobiega
Pobiega•9mo ago
Yep. If you want to set the relations via a constructor, include two constructors One for models and one for just ids
Timo Martinson
Timo MartinsonOP•9mo ago
what do you mean? how would they look like?
Pobiega
Pobiega•9mo ago
I'm on mobile ATM so don't really want to type out code :p
Timo Martinson
Timo MartinsonOP•9mo ago
oh ok
Pobiega
Pobiega•9mo ago
But two identical constructors, one with complex objects for the relations, and the other with only IDs for those relations All non-nav props set in both constructors
Timo Martinson
Timo MartinsonOP•9mo ago
why would I do this?
Pobiega
Pobiega•9mo ago
Because otherwise you get issues 🙂
Timo Martinson
Timo MartinsonOP•9mo ago
uh. I don't get it yet. 😦
Pobiega
Pobiega•9mo ago
Ef will use the is constructor internally, even if it's private Id*
Timo Martinson
Timo MartinsonOP•9mo ago
aaaaand in general: How to type out 2 constructors?
Pobiega
Pobiega•9mo ago
Just make two :p I'm not sure I'd use primary constructors for this either However, you can also skip ctors entirely, since your models are fully externally mutable All your setters are public
Timo Martinson
Timo MartinsonOP•9mo ago
what does that mean?
Pobiega
Pobiega•9mo ago
Do you not understand access modifiers?
Timo Martinson
Timo MartinsonOP•9mo ago
I do.
Pobiega
Pobiega•9mo ago
Public Vs private etc
Timo Martinson
Timo MartinsonOP•9mo ago
I understand.
Pobiega
Pobiega•9mo ago
Okay, then I don't understand the question
Timo Martinson
Timo MartinsonOP•9mo ago
mmmh. sorry I understand now.
Pobiega
Pobiega•9mo ago
What I personally prefer to do is... * Mostly private setters * Private EF constructor with IDs * Public ctor for my own code to use
Timo Martinson
Timo MartinsonOP•9mo ago
I am just starting out. Am open for everything.
Pobiega
Pobiega•9mo ago
The only thing unique to EF is that you must have a setter for any prop that should be database tracked, but it can be private
Timo Martinson
Timo MartinsonOP•9mo ago
yeah, ok.
Pobiega
Pobiega•9mo ago
And that EF can't set navigation properties from a constructor
Timo Martinson
Timo MartinsonOP•9mo ago
yes, I experienced that already
Pobiega
Pobiega•9mo ago
That's why you need a constructor with the ids
Timo Martinson
Timo MartinsonOP•9mo ago
maybe you can post a code snippet later?
Pobiega
Pobiega•9mo ago
Sure ~ 45 mins or so
Timo Martinson
Timo MartinsonOP•9mo ago
would be great
Pobiega
Pobiega•9mo ago
public class Comment
{
// public ctor for use in code
public Comment(string name, string content, User? user, Post? post)
{
Name = name;
Content = content;
User = user;
Post = post;
CreatedAt = DateTimeOffset.Now;
UpdatedAt = DateTimeOffset.Now;
}

// private ctor for EF
private Comment(Guid id, string name, string content, Guid? userId, Guid? postId, DateTimeOffset createdAt, DateTimeOffset updatedAt)
{
Id = id;
Name = name;
Content = content;
UserId = userId;
PostId = postId;
CreatedAt = createdAt;
UpdatedAt = updatedAt;
}

public Guid Id { get; private set; } // let EF/database set the pkey

// should these be externally mutable?
public string Name { get; set; }
public string Content { get; set; }

// don't use DateTime! Use DateTimeOffset
public DateTimeOffset CreatedAt { get; private set; }
public DateTimeOffset UpdatedAt { get; private set; }

public User? User { get; set; } // should this really be nullable? a comment without a user?
public Guid? UserId { get; set; }

public Post? Post { get; set; }
public Guid? PostId { get; set; }
}
public class Comment
{
// public ctor for use in code
public Comment(string name, string content, User? user, Post? post)
{
Name = name;
Content = content;
User = user;
Post = post;
CreatedAt = DateTimeOffset.Now;
UpdatedAt = DateTimeOffset.Now;
}

// private ctor for EF
private Comment(Guid id, string name, string content, Guid? userId, Guid? postId, DateTimeOffset createdAt, DateTimeOffset updatedAt)
{
Id = id;
Name = name;
Content = content;
UserId = userId;
PostId = postId;
CreatedAt = createdAt;
UpdatedAt = updatedAt;
}

public Guid Id { get; private set; } // let EF/database set the pkey

// should these be externally mutable?
public string Name { get; set; }
public string Content { get; set; }

// don't use DateTime! Use DateTimeOffset
public DateTimeOffset CreatedAt { get; private set; }
public DateTimeOffset UpdatedAt { get; private set; }

public User? User { get; set; } // should this really be nullable? a comment without a user?
public Guid? UserId { get; set; }

public Post? Post { get; set; }
public Guid? PostId { get; set; }
}
I'd probably have the nav props be private set too, as for the Ids, to be honest 😛
Timo Martinson
Timo MartinsonOP•9mo ago
Hooo, thanks, master. just one thing: "private member is not used" ... member: private Comment.Comment ....
Pobiega
Pobiega•9mo ago
? Oh, you have some analyzer that says the private constructor isnt used downsides of static analysis, it doesnt take ORMs and reflection into account 🙂 EF can and will use that private constructor. you can comment it out and your program wont work, or have it and it will work
Timo Martinson
Timo MartinsonOP•9mo ago
Well, I have to admit: You are my hero of this day. 😉 Thank you soooo much. now the puzzle in my head fits together
Pobiega
Pobiega•9mo ago
np its a bit weird at first, with how EF can use private setters/ctors, and how it populates the values as needed when you do selects etc Pob's EF tips: * Don't use repositories over EF! Use the context, and almost all queries should include a Select!
Angius
Angius•9mo ago
Since I started using required properties, constructors seem like bloat lol
Pobiega
Pobiega•9mo ago
Have not yet started messing about with required on entities tbh doesnt help that we have audit trails on most of our entities
Timo Martinson
Timo MartinsonOP•9mo ago
The non-nullable property "User" must contain a value not equal to NULL upon exiting the constructor. Consider declaring the "Property" as nullable. The non-nullable property "Post" must contain a value not equal to NULL upon exiting the constructor. Consider declaring the "Property" as nullable. UUUUH. What should I do? I get these messages
Pobiega
Pobiega•9mo ago
you removed the nullability on the props I guess?
Timo Martinson
Timo MartinsonOP•9mo ago
yes, as you told me ! 😉
Pobiega
Pobiega•9mo ago
hah yep yeah, so, there are a few ways to get around it the quick and dirty is to set them to = null!
Timo Martinson
Timo MartinsonOP•9mo ago
uh and the other one? are there any downsides using = null!
Pobiega
Pobiega•9mo ago
use a nullable backing field for the prop and throw when accessed if its null
Timo Martinson
Timo MartinsonOP•9mo ago
?
Pobiega
Pobiega•9mo ago
well, you do get nullability problems when using the entity "outside" of EF queries if you fetch it without including the nav prop, it will be null regardless - but your type indicates that its not possible. not a very nice error. but you also dont want to be forced to always include the nav prop, that makes queries much slower I guess a decent workaround is to have it be non-nullable in the constructor, but nullable on the property. combine that with a private set and you should be fine or no, you wont actually nvm that. the migration would generate wrong
Timo Martinson
Timo MartinsonOP•9mo ago
thank you! have a good time, bye!
[HttpPost("/blog/{blogSlug}/post")]
public async Task<Post> CreatePost([FromBody] Post newPost, [FromRoute] string blogSlug)
{
Blog blog = await _dataContext.Blogs.FirstAsync((b) => b.Slug == blogSlug);
newPost.Blog = blog;
await _dataContext.Posts.AddAsync(newPost);
await _dataContext.SaveChangesAsync();

return newPost;
}
[HttpPost("/blog/{blogSlug}/post")]
public async Task<Post> CreatePost([FromBody] Post newPost, [FromRoute] string blogSlug)
{
Blog blog = await _dataContext.Blogs.FirstAsync((b) => b.Slug == blogSlug);
newPost.Blog = blog;
await _dataContext.Posts.AddAsync(newPost);
await _dataContext.SaveChangesAsync();

return newPost;
}
The message:
"errors": {
"Blog": [
"The Blog field is required."
],
"User": [
"The User field is required."
]
},
"errors": {
"Blog": [
"The Blog field is required."
],
"User": [
"The User field is required."
]
},
what can I do about it?
Angius
Angius•9mo ago
Provide the required values...?
Timo Martinson
Timo MartinsonOP•9mo ago
I thought i have done it with newPost.Blog = blog ??
Angius
Angius•9mo ago
Your action method takes a Post from the request body So it expects all properties of that post, that are not nullable, to be filled If you want to set some properties later, or if you want the form to not send all of the properties of a post, use a DTO class One that only has the properties required Based on that, you can then create the actual post
Timo Martinson
Timo MartinsonOP•9mo ago
oh, thanks. what's a DTO class?
Angius
Angius•9mo ago
Data Transfer Object, meaning a class whose sole purpose is to be a container for data It has no code besides properties, basically
public sealed class PostDto
{
public required string Title { get; init; }
public required string Body { get; init; }
public required int AuthorId { get; init; }
}
public sealed class PostDto
{
public required string Title { get; init; }
public required string Body { get; init; }
public required int AuthorId { get; init; }
}
for example
Timo Martinson
Timo MartinsonOP•9mo ago
thanks. sealed ? what's that?
Angius
Angius•9mo ago
It means the class cannot be inherited from
Timo Martinson
Timo MartinsonOP•9mo ago
ok
[HttpPost("/user")]
public async Task<User> CreateUser([FromBody] UserData userData)
{
await _dataContext.Users.AddAsync(userData);
await _dataContext.SaveChangesAsync();

return userData;
}
[HttpPost("/user")]
public async Task<User> CreateUser([FromBody] UserData userData)
{
await _dataContext.Users.AddAsync(userData);
await _dataContext.SaveChangesAsync();

return userData;
}
Warning for UserData ... Argument "1": Conversion of "Textopia.Models.UserData" to "Textopia.Models.User" not possible.
public sealed class UserData(string name, string slug, string description, string email, string password)
{
public string Name { get; set; } = name;
public string Slug { get; set; } = slug;
public string Description { get; set; } = description;

public string Email { get; set; } = email;
public string Password { get; set; } = password;
}
public sealed class UserData(string name, string slug, string description, string email, string password)
{
public string Name { get; set; } = name;
public string Slug { get; set; } = slug;
public string Description { get; set; } = description;

public string Email { get; set; } = email;
public string Password { get; set; } = password;
}
this is the DTO class
Angius
Angius•9mo ago
Well, yeah (don't use AddAsync btw)
Timo Martinson
Timo MartinsonOP•9mo ago
why not use async?
Angius
Angius•9mo ago
It's used only for very specific edge cases
Timo Martinson
Timo MartinsonOP•9mo ago
good
Angius
Angius•9mo ago
As it does no database IO, it doesn't need to be asynchronous Only .SaveChangesAsync() actually calls the db, so this one does need to be async Regardless, you will have to map the data from your DTO to your actual database model (also, I'd remove the primary constructor from the DTO, it's not needed, properties alone are fine)
Timo Martinson
Timo MartinsonOP•9mo ago
My code analyzer complains if I remove the Asnyc from AddAsync !
Angius
Angius•9mo ago
Do you still await it?
Timo Martinson
Timo MartinsonOP•9mo ago
yap
Angius
Angius•9mo ago
Don't
Timo Martinson
Timo MartinsonOP•9mo ago
good
Angius
Angius•9mo ago
It's not asynchronous, it doesn't need to be awaited
Timo Martinson
Timo MartinsonOP•9mo ago
the same with "FirstAsync" ?
Angius
Angius•9mo ago
No, this one calls the database So it needs to be asynchronous
Timo Martinson
Timo MartinsonOP•9mo ago
uh then ... ok
Angius
Angius•9mo ago
Only Add/AddRange/Delete/DeleteRange/Update should be non-async
Timo Martinson
Timo MartinsonOP•9mo ago
how to translate DTO to Model ?
Angius
Angius•9mo ago
Either manually, or with something like Riok.Mapperly
Timo Martinson
Timo MartinsonOP•9mo ago
Manually is fine can you help me with this? or should I reach out to the internet ?
Angius
Angius•9mo ago
Manual example:
// database model
public sealed class Blogpost
{
public required string Title { get; set; }
public required string Body { get; set; }
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.Now;
}

// DTO
public sealed class BlogpostDto
{
public required string Title { get; init; }
public required string Body { get; init; }
}

// handler
[HttpPost("/blogpost")]
public async Task<IActionResult> CreateUser([FromBody] BlogpostDto data)
{
var post = new Blogpost {
Title = data.Title,
Body = data.Body,
};
_context.Blogposts.Add(post);
await _context.SaveChangesAsync();

return Ok();
}
// database model
public sealed class Blogpost
{
public required string Title { get; set; }
public required string Body { get; set; }
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.Now;
}

// DTO
public sealed class BlogpostDto
{
public required string Title { get; init; }
public required string Body { get; init; }
}

// handler
[HttpPost("/blogpost")]
public async Task<IActionResult> CreateUser([FromBody] BlogpostDto data)
{
var post = new Blogpost {
Title = data.Title,
Body = data.Body,
};
_context.Blogposts.Add(post);
await _context.SaveChangesAsync();

return Ok();
}
Timo Martinson
Timo MartinsonOP•9mo ago
Do I have to create another constructor in the model? because:
No argument was provided that corresponds to the required parameter 'name' of 'User.User(string, string, string, string, string)'.
No argument was provided that corresponds to the required parameter 'name' of 'User.User(string, string, string, string, string)'.
just another error message
Angius
Angius•9mo ago
As you will observe in my code, it does not use any constructors Instead, it makes use of required properties
Timo Martinson
Timo MartinsonOP•9mo ago
now I see would DTOs work WITH constructors, as I rely on them?
namespace Textopia.Models;

public class User
{
public Guid Id { get; private set; }

public string Name { get; set; }
public string Slug { get; set; }
public string Description { get; set; }

public string Email { get; set; }
public string Password { get; set; }

public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.Now;
public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.Now;

public List<Blog> Blogs { get; set; } = [];
public List<Post> Posts { get; set; } = [];
public List<Comment> Comments { get; set; } = [];

public User(string name, string slug, string description, string email, string password)
{
Name = name;
Slug = slug;
Description = description;

Email = email;
Password = password;

CreatedAt = DateTimeOffset.Now;
UpdatedAt = DateTimeOffset.Now;
}

private User(Guid id, string name, string slug, string description, string email, string password, DateTimeOffset createdAt, DateTimeOffset updatedAt)
{
Id = id;

Name = name;
Slug = slug;
Description = description;

Email = email;
Password = password;

CreatedAt = createdAt;
UpdatedAt = updatedAt;
}
}

public sealed class UserData(string name, string slug, string description, string email, string password)
{
public string Name { get; init; } = name;
public string Slug { get; init; } = slug;
public string Description { get; init; } = description;

public string Email { get; init; } = email;
public string Password { get; init; } = password;
}
namespace Textopia.Models;

public class User
{
public Guid Id { get; private set; }

public string Name { get; set; }
public string Slug { get; set; }
public string Description { get; set; }

public string Email { get; set; }
public string Password { get; set; }

public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.Now;
public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.Now;

public List<Blog> Blogs { get; set; } = [];
public List<Post> Posts { get; set; } = [];
public List<Comment> Comments { get; set; } = [];

public User(string name, string slug, string description, string email, string password)
{
Name = name;
Slug = slug;
Description = description;

Email = email;
Password = password;

CreatedAt = DateTimeOffset.Now;
UpdatedAt = DateTimeOffset.Now;
}

private User(Guid id, string name, string slug, string description, string email, string password, DateTimeOffset createdAt, DateTimeOffset updatedAt)
{
Id = id;

Name = name;
Slug = slug;
Description = description;

Email = email;
Password = password;

CreatedAt = createdAt;
UpdatedAt = updatedAt;
}
}

public sealed class UserData(string name, string slug, string description, string email, string password)
{
public string Name { get; init; } = name;
public string Slug { get; init; } = slug;
public string Description { get; init; } = description;

public string Email { get; init; } = email;
public string Password { get; init; } = password;
}
this is all I have. chatGPT suggests this:
public User(UserData userData) : this(Guid.NewGuid(), userData.Name, userData.Slug, userData.Description, userData.Email, userData.Password, DateTimeOffset.Now, DateTimeOffset.Now)
{

}
public User(UserData userData) : this(Guid.NewGuid(), userData.Name, userData.Slug, userData.Description, userData.Email, userData.Password, DateTimeOffset.Now, DateTimeOffset.Now)
{

}
what do you think?
Pobiega
Pobiega•9mo ago
absolutely not the entity should not be aware of the DTO existing
Timo Martinson
Timo MartinsonOP•9mo ago
mmh then what?
Pobiega
Pobiega•9mo ago
static methods on the DTO FromEntity/ToEntity if anything I guess ToEntity wont be a static method thou
Timo Martinson
Timo MartinsonOP•9mo ago
uh I understand
Angius
Angius•9mo ago
How do you rely on constructors for DTOs, if you never instantiate that incoming DTO yourself? ASP binds form values to it You never touch the ctor
Timo Martinson
Timo MartinsonOP•9mo ago
I don't understand you.
Angius
Angius•9mo ago
[HttpPost]
public async Task<blah> DoStuff([FromForm] MyCoolDto data) {...}
[HttpPost]
public async Task<blah> DoStuff([FromForm] MyCoolDto data) {...}
You never create an instance of MyCoolDto It should not matter for you, whatsoever, whether it has a constructor or not So I wonder, why are you "relying on them"
Timo Martinson
Timo MartinsonOP•9mo ago
I have created a whole project with constructors.
Angius
Angius•9mo ago
So? Use them when they're useful Don't use them if they're not
Timo Martinson
Timo MartinsonOP•9mo ago
could you help me with my DTO ?
Angius
Angius•9mo ago
I did
Timo Martinson
Timo MartinsonOP•9mo ago
I know but not the way I desired
public sealed class UserData(string name, string slug, string description, string email, string password)
{
public string Name { get; init; } = name;
public string Slug { get; init; } = slug;
public string Description { get; init; } = description;

public string Email { get; init; } = email;
public string Password { get; init; } = password;

public static void FromUser()
{

}

public static void ToUser()
{

}
}
public sealed class UserData(string name, string slug, string description, string email, string password)
{
public string Name { get; init; } = name;
public string Slug { get; init; } = slug;
public string Description { get; init; } = description;

public string Email { get; init; } = email;
public string Password { get; init; } = password;

public static void FromUser()
{

}

public static void ToUser()
{

}
}
Pobiega
Pobiega•9mo ago
remove static from ToUser and just do return new User(... data from dto here...) also, most of the time you have separate DTOs for in and out. in fact, you might have several "out" dtos for a single entity it all depends on what data you need for what endpoint in your api
Angius
Angius•9mo ago
public sealed class UserData
{
public required string Name { get; init; }
public required string Slug { get; init; }
public required string Description { get; init; }
public required string Email { get; init; }
public required string Password { get; init; }

public static UserData FromUser(User user) => new UserData {
Name = user.Name,
Slug = user.Slug,
// ...
};

public User ToUser() => new User {
Name = Name,
Slug = Slug,
// ...
};
}
public sealed class UserData
{
public required string Name { get; init; }
public required string Slug { get; init; }
public required string Description { get; init; }
public required string Email { get; init; }
public required string Password { get; init; }

public static UserData FromUser(User user) => new UserData {
Name = user.Name,
Slug = user.Slug,
// ...
};

public User ToUser() => new User {
Name = Name,
Slug = Slug,
// ...
};
}
Here
Timo Martinson
Timo MartinsonOP•9mo ago
can I use required props in UserData AND not use them in my models?
Angius
Angius•9mo ago
No, once you ever type required anywhere you must use it for every property, otherwise the compiler will hijack your microwave and explode it You can, of course you can If you're dead-set on using constructors and suffering headaches that go with that decision, sure
Timo Martinson
Timo MartinsonOP•9mo ago
I am just new to the whole thing.
Angius
Angius•9mo ago
You can even use a constructor here, if you love writing a lot of useless code
public sealed class UserData(string name, string slug, string description, string email, string password)
{
// you will need the default constructor anyway
// which will probably require you to make the properties `required` anyway
// for no reason at all, because neither the framework nor you will ever use the non-default constructor
public UserData(){}

public string Name { get; init; } = name;
public string Slug { get; init; } = slug;
public string Description { get; init; } = description;
public string Email { get; init; } = email;
public string Password { get; init; } = password;

public static UserData FromUser(User user) => new UserData(
user.Name,
user.Slug,
// ...
);

public User ToUser() => new User {
Name = Name,
Slug = Slug,
// ...
};
}
public sealed class UserData(string name, string slug, string description, string email, string password)
{
// you will need the default constructor anyway
// which will probably require you to make the properties `required` anyway
// for no reason at all, because neither the framework nor you will ever use the non-default constructor
public UserData(){}

public string Name { get; init; } = name;
public string Slug { get; init; } = slug;
public string Description { get; init; } = description;
public string Email { get; init; } = email;
public string Password { get; init; } = password;

public static UserData FromUser(User user) => new UserData(
user.Name,
user.Slug,
// ...
);

public User ToUser() => new User {
Name = Name,
Slug = Slug,
// ...
};
}
In general, though, remember that language features are tools You use them when they're needed And don't use them when they're not You don't see people trying to cut wood using a screwdriver because they're committed to using a screwdriver for their project They probably set the screwdriver aside and pick up a saw
Timo Martinson
Timo MartinsonOP•9mo ago
When to use "record"s in C# ? ... btw
Angius
Angius•9mo ago
Ah, a very good question! Records would be ideal for DTOs, actually They're immutable, which makes sense for a DTO since you don't want to be modifying the incoming data The syntax is also super short, so your DTOs can even exist next to actions or handlers, no need for separate files They also offer some nice stuff like value-type comparison or desconstruction
Timo Martinson
Timo MartinsonOP•9mo ago
k. 😦 I just dont understand how to translate DTO to Model.
Angius
Angius•9mo ago
var thing = new Model {
Foo = dto.Foo,
Bar = dto.Bar,
Baz = dto.Baz
};
var thing = new Model {
Foo = dto.Foo,
Bar = dto.Bar,
Baz = dto.Baz
};
Or, if Model has a constructor,
var thing = new Model(dto.Foo, dto.Bar, dto.Baz);
var thing = new Model(dto.Foo, dto.Bar, dto.Baz);
Or, with a ToModel() method on the DTO,
var thing = dto.ToModel();
var thing = dto.ToModel();
Timo Martinson
Timo MartinsonOP•9mo ago
so... Now I understand. Thank you very much and have a good time, ZZZZZZZZZ ...
Want results from more Discord servers?
Add your server