У меня есть организация DataSuggestion
, которой принадлежит Data
. Data
сама владеет Material
и Coordinates
.
public class DataSuggestion : Entity<Guid>
{
public Guid DataId { get; init; }
public Email Email { get; init; }
public Comment Comment { get; init; }
public Data Data { get; init; }
public DataSuggestion(Email email,
Comment comment,
IEnumerable<Coordinate> coordinates,
Material material) : this()
{
Email = email;
Comment = comment;
Data = new Data(coordinates, material);
}
private DataSuggestion()
{ }
}
public class Data : ValueObject<Data>
{
private readonly List<Coordinate> _coordinates;
public IEnumerable<Coordinate> Coordinates => _coordinates.AsReadOnly();
public Material Material { get; init; }
public Data(IEnumerable<Coordinate> coordinates,
Material material) : this()
{
_coordinates = coordinates.ToList();
Material = material;
}
/// <summary>
/// EF Core constructor
/// </summary>
private Data()
{ }
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
return [_coordinates, Material];
}
}
Конфигурация следующая
builder.OwnsOne(ds => ds.Comment);
builder.OwnsOne(ds => ds.Email);
builder.OwnsOne(ds => ds.Data, ownedNavigationBuilder =>
{
ownedNavigationBuilder.OwnsOne(d => d.Material);
ownedNavigationBuilder.OwnsMany(d => d.Coordinates);
ownedNavigationBuilder.Navigation(d => d.Material).IsRequired();
});
Я получаю исключение:
Тип сущности «Данные» — это необязательная зависимость, использующая совместное использование таблиц и содержащая другие зависимые объекты без какого-либо обязательного общего свойства, позволяющего определить, существует ли сущность. Если все свойства, допускающие значение NULL, содержат нулевое значение в базе данных, то экземпляр объекта не будет создан в запросе, что приведет к потере значений вложенных зависимых объектов. Добавьте обязательное свойство, чтобы создавать экземпляры с нулевыми значениями для других свойств, или отметьте входящую навигацию как обязательную, чтобы всегда создавать экземпляр.
Насколько я понимаю, исключение гласит, что ни одно из свойств Data
не должно быть нулевым. Однако я уже отметил Материал как необходимый (Обновлено: я имею в виду ownedNavigationBuilder.Navigation(d => d.Material).IsRequired();
), и сделать то же самое для коллекций невозможно.
Также я немного смущен: DataSuggestion
владеет Comment
, который содержит только строковое свойство, но такое исключение не генерируется.
Я пытался пометить целое Data
как необходимое, но безрезультатно.
Вопросы следующие:
Coordinates
как обязательное?Спасибо!
Обновлено: я обнаружил, что порядок инструкций имеет значение, и если я поставлю
uilder.Navigation(ds => ds.Data).IsRequired();
После
builder.OwnsOne(ds => ds.Data, ownedNavigationBuilder =>
{
ownedNavigationBuilder.OwnsOne(d => d.Material);
ownedNavigationBuilder.Navigation(d => d.Material).IsRequired();
ownedNavigationBuilder.OwnsMany(d => d.Coordinates);
});
Тогда это работает, но все же почему этого недостаточно?
ownedNavigationBuilder.Navigation(d => d.Material).IsRequired();
Когда вы говорите «отмечено как необходимое» — вы имеете в виду, что использовали модификатор required
, атрибут [Required]
или что-то еще? Если вы имели в виду модификатор required
, то вы не можете этого сделать: он не работает с EF, потому что EF всегда может загрузить один объект без каких-либо других связанных объектов (т. е. await dbContext.DataSuggestion.ToListAsync()
без выполнения await dbContext.DataSuggestion.Include( ds => ds.Material ).Include( ds => ds.Coordinates ).ToListAsync()
- поэтому вы не можете сделать EF свойства навигации required
и почему их также следует отмечать как #nullable
.
Обратите внимание, что вам необходимо убедиться, что это сделано так, что оно не меняет природу «обязательного» или «необнуляемого» ограничения FK — вы все равно можете иметь их — но свойства ссылки на класс сущности .NET должны быть обнуляемыми, потому что свойства навигации всегда могут быть null
, если вы не загружаете связанные объекты (и если у вас отключена отложенная загрузка, что вам следует иметь...)
@Dai Я обновил пост, сначала должен был опубликовать классы
@Дай, извини за путаницу, я имею в виду [Обязательно] (или .IsRequired(), как я это объявил)
Material
и Coordinates
— это не свойства, а принадлежащие типы/коллекции, и если Data
сам по себе не содержит каких-либо ненулевых свойств, то ни один экземпляр Data
не будет создан, независимо от значений Material
.
Я аннотировал сообщение об исключении, чтобы объяснить его.
Тип сущности «Данные» является необязательной зависимостью (вы не использовали .IsRequired() для самого
Data
) с использованием совместного использования таблиц и содержащий других иждивенцев (Material
иCoordinates
) без какого-либо обязательного общего свойства (Data
не содержит свойства, принадлежащие типы/коллекции не учитываются) чтобы определить, существует ли сущность. Если все свойства, допускающие значение NULL (это тот случай, если у вас нет свойств) содержать нулевое значение в базе данных, то экземпляр объекта (Data
) не будет созданный в запросе, приводящий к потере значений вложенных зависимостей (Material
). Добавлять необходимое свойство для создания экземпляров с нулевыми значениями для других свойства или отметьте входящую навигацию как необходимую, чтобы всегда создать экземпляр.
Пожалуйста, опубликуйте определение
class DataSuggestion
иclass Data
.