C
C#4d ago
surwren

My constructor sets the attribute, so why is EFcore complaining?

why is EFCore complaining? Required member 'UpMedia.OwnerId' must be set in the object initializer or attribute constructor. Required member 'UpMedia.Owner' must be set in the object initializer or attribute constructor. Here: var upMedia = new UpMedia(upMediaDto.Type, user, upMediaDto.Bucket, upMediaDto.Path); My code is
try
{
int OnaId = await HttpHandler.GetOnaIdAsync(client, userInfoUri, token);
var user = await _userService.GetUserByOnaIdAsync(OnaId);
if (user == null)
{
user = await _userService.CreateUserByOnaIdAsync(OnaId);
//return NotFound("User not found. Call the \"Ona/Token\" Get/Put methods in api/Users first");
}
var upMedia = new UpMedia(upMediaDto.Type, user, upMediaDto.Bucket, upMediaDto.Path);
var createdUpMedia = await _upMediaService.CreateUpMediaAsync(upMedia);
return Ok(UpMediaMapper.ToUpMediaDto(createdUpMedia));
...
try
{
int OnaId = await HttpHandler.GetOnaIdAsync(client, userInfoUri, token);
var user = await _userService.GetUserByOnaIdAsync(OnaId);
if (user == null)
{
user = await _userService.CreateUserByOnaIdAsync(OnaId);
//return NotFound("User not found. Call the \"Ona/Token\" Get/Put methods in api/Users first");
}
var upMedia = new UpMedia(upMediaDto.Type, user, upMediaDto.Bucket, upMediaDto.Path);
var createdUpMedia = await _upMediaService.CreateUpMediaAsync(upMedia);
return Ok(UpMediaMapper.ToUpMediaDto(createdUpMedia));
...
public class UpMedia : BaseUpload
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
public MediaType Type { get; set; } // Metadata

// Navigation property
public required Guid OwnerId { get; set; }
public required User Owner { get; set; } // must always be present

public ICollection<Post> Posts { get; set; }

public UpMedia() : base()
{
Posts = new HashSet<Post>();
}
public UpMedia(MediaType Type, User Owner, string Bucket, string Path) : base(Bucket, Path)
{
this.Type = Type;
this.OwnerId = Owner.Id;
this.Owner = Owner;
this.Posts = new HashSet<Post>();
}

}
public class UpMedia : BaseUpload
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
public MediaType Type { get; set; } // Metadata

// Navigation property
public required Guid OwnerId { get; set; }
public required User Owner { get; set; } // must always be present

public ICollection<Post> Posts { get; set; }

public UpMedia() : base()
{
Posts = new HashSet<Post>();
}
public UpMedia(MediaType Type, User Owner, string Bucket, string Path) : base(Bucket, Path)
{
this.Type = Type;
this.OwnerId = Owner.Id;
this.Owner = Owner;
this.Posts = new HashSet<Post>();
}

}
???????
15 Replies
Brumla
Brumla4d ago
please try it like this:
var media = new UpMedia("myOtherValue") {
OwnerId = Guid.NewGuid()
};

class UpMedia {
public required Guid OwnerId {get;set;}
public string SomeOtherValue {get;set;}

public UpMedia(string someOtherValue) {
SomeOtherValue = someOtherValue;
}
}
var media = new UpMedia("myOtherValue") {
OwnerId = Guid.NewGuid()
};

class UpMedia {
public required Guid OwnerId {get;set;}
public string SomeOtherValue {get;set;}

public UpMedia(string someOtherValue) {
SomeOtherValue = someOtherValue;
}
}
of course, you can initialize all the properties in the same way like the UpMedia property in fact, the complains go from the C# itself as you have to use object initializer to initialize the properties here.
surwren
surwrenOP4d ago
you have to use object initializer to initialize the properties here
beg your pardon what is object initalizer the empty constructor?
Brumla
Brumla4d ago
no, this is the part in those {} brackets: var somevar = new MyClass(... here goes constructor args...) { someProperty = someInitialValueForRequiredProperty, otherProperty = otherValue}
Brumla
Brumla4d ago
Object and Collection Initializers - C#
Object initializers in C# assign values to accessible fields or properties of an object at creation after invoking a constructor.
FusedQyou
FusedQyou4d ago
Nothing about this question has anything to do with EFCore This is a class used in EFCore, but the compiler is the one telling you about the issue The error means you must set all properties and fields that require a value and can't be null. These are OwnerId and Owner
public UpMedia() : base()
{
Posts = new HashSet<Post>();
}
public UpMedia() : base()
{
Posts = new HashSet<Post>();
}
This one doesn't set them Maybe you are confused because you think base() calls the other constructor. It does not. You'd use this() So, either fix this constructor and set the values, or giveOwnerId and Owner a value. Alternatively, use null-forgiving operators and tell the compiler the value can be null.
public UpMedia() : base()
{
Posts = new HashSet<Post>();
giveOwnerId = null!;
Owner = null!;
}
public UpMedia() : base()
{
Posts = new HashSet<Post>();
giveOwnerId = null!;
Owner = null!;
}
Note that the values will be null but the compiler won't tell you. ONLY use this if you are aware that they will be null in the context, and/or they are given a value soon after. Also, this doesn't solve anything Oh, nevermind. I misunderstand the question
Brumla
Brumla4d ago
it solves the problem when the required is used, I don`t take care about the background why this is set in this way in EF entity.
FusedQyou
FusedQyou4d ago
@surwren when you have required on properties you must set them in the object initializer. Remove those You already have constructors. Use one or the other Considering this is an EF class you might just want to remove the constructors instead because EF works easier with required properties rather than constructors
surwren
surwrenOP4d ago
var upMedia = new UpMedia(upMediaDto.Type, user, upMediaDto.Bucket, upMediaDto.Path); does this not explicitly set the required variables?
FusedQyou
FusedQyou4d ago
No, the constructor is unrelated to the required keyword Because when a constructor is made, it has its own requirements by default required is purely for object initializers
surwren
surwrenOP4d ago
public UpMedia(MediaType Type, User Owner, string Bucket, string Path) : base(Bucket, Path)
{
this.Type = Type;
this.OwnerId = Owner.Id;
this.Owner = Owner;
this.Posts = new HashSet<Post>();
}
public UpMedia(MediaType Type, User Owner, string Bucket, string Path) : base(Bucket, Path)
{
this.Type = Type;
this.OwnerId = Owner.Id;
this.Owner = Owner;
this.Posts = new HashSet<Post>();
}
it sets the owner and ownerid explicitly i dont get it what is the difference between constructor and object initializer or do you mean this?
new UpMedia() {
//set attributes here
}
new UpMedia() {
//set attributes here
}
but im not even using that :harold: i dont understand i thought required makes EFcore deduce that this object is dependent on the other one or something similar meaning that one User can have 0 or many UpMedia but every UpMedia must have one user
FusedQyou
FusedQyou4d ago
So remove required That's what I said If you don't use an object initializer required is useless No, EFCore doesn't care It checks nullabillity
333fred
333fred4d ago
You're probably thinking of the Required attribute. But FsQyou is right, since C# 8 (.NET Core 3.1) EF can just use nullability directly
surwren
surwrenOP3d ago
I saw the [Required] annotation in a couple places before and didn't really understand the difference from the required keyword Need to research that after I get stuff done
333fred
333fred3d ago
They're not related
Want results from more Discord servers?
Add your server