Нет неявного преобразования ссылки из X в Y

avatar
BeniaminoBaggins
9 августа 2021 в 01:03
70
0
0

У меня ошибка в объявлении этого класса:

public class MenuItemEstablishmentsRepository : VeganItemEstablishmentsRepository<MenuItem, Restaurant, MenuItemTag>
{

Ошибка:

Тип Vepo.Domain.MenuItem нельзя использовать в качестве параметра типа 'TVeganItem' в универсальном типе или методе 'VeganItemEstablishmentsRepository<TVeganItem, TEstablishment, TVeganItemTag>'. Нет неявного преобразования ссылок из 'Vepo.Domain.MenuItem' для 'Vepo.Domain.VeganItem<Vepo.Common.Enums.MenuItemTag, Vepo.Domain.VeganItemEstablishment<Vepo.Domain.MenuItem, Вепо.Домен.Ресторан>>'. [Вепо.Данные]

MenuItem и VeganItem:

[ElasticsearchType(RelationName = "menuitem", IdProperty = "Id")]
public class MenuItem : VeganItem<MenuItemTag, MenuItemEstablishment>
{
}


using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Nest;
using Newtonsoft.Json;

namespace Vepo.Domain
{
    [Serializable]
    public abstract class VeganItem<TVeganItemTag, TVeganItemEstablishment> : DomainEntity<int>
    {
        [Required]
        public string Name { get; set; }
        [Required]
        public string CompanyName { get; set; }
        [Required]
        public string Description { get; set; }
        public string Image { get; set; }
        [Required]
        public int IsNotVeganCount { get; set; } = 0;
        [Required]
        public int IsVeganCount { get; set; } = 0;
        [Required]
        public int RatingsCount { get; set; } = 0;
        [Required]
        public int Rating { get; set; }
        [Required]
        public List<TVeganItemTag> Tags { get; set; }

        [PropertyName("veganItemEstablishments", Ignore = true)]
        public virtual ICollection<TVeganItemEstablishment> VeganItemEstablishments { get; set; }
    }
}

Почему он не может преобразовать MenuItem в VeganItem, когда MenuItem наследуется от VeganItem? Как обойти эту ошибку?

Суперрепозиторий:

public abstract class VeganItemEstablishmentsRepository
    <TVeganItem, TEstablishment, TVeganItemTag> : 
    Repository<VeganItemEstablishment<TVeganItem, TEstablishment>  int> 
    where TVeganItem : VeganItem<TVeganItemTag, VeganItemEstablishment<TVeganItem, TEstablishment>>
    where TEstablishment : Establishment<VeganItemEstablishment<TVeganItem, TEstablishment>>
Источник
Jeremy Lakeman
9 августа 2021 в 01:20
0

Почему в репозитории есть только сложные ограничения where? Если единственный действительный VeganItem также имеет ограничение VeganItemEstablishment, почему бы не определить это правило для элемента? Но действительно ли вам нужны эти сложные ограничения?

BeniaminoBaggins
9 августа 2021 в 01:32
0

@JeremyLakeman Я не знаю, нужны ли мне ограничения where. Я заметил, что когда я добавлял ограничения в VeganItem, это означало, что мне нужно было передать больше типов в VeganItem, поэтому это выглядело неуклюжим. Мы не можем использовать абстрактные классы в таблицах, верно? Вот почему я думаю, что мне нужны все эти универсальные типы, если я хочу сделать код пригодным для повторного использования.

Jeremy Lakeman
9 августа 2021 в 01:37
0

Сколько похожих, но немного разных таблиц вы создаете? Как вы планируете запрашивать их? Это не похоже на хороший дизайн реляционной базы данных.

BeniaminoBaggins
9 августа 2021 в 01:45
0

@JeremyLakeman Запросы к ним кажутся простыми, поскольку все они наследуются от одного и того же суперкласса, я могу ввести их как суперкласс (но я разработчик интерфейса, поэтому я могу ошибаться). Но да, я думаю, что мне не нужны все эти подклассы. Подклассы очень похожи. Они отличаются только тем, что tags — это другое перечисление. Может быть, я должен сделать это int? Я также подумал, что этот дизайн позволит мне изменять их по мере развития приложения, которое может быть более гибким.

BeniaminoBaggins
9 августа 2021 в 01:50
0

@JeremyLakeman в будущем может быть до 20 подклассов VeganItem. Но, может быть, я мог бы сделать VeganItem конкретным классом и просто использовать его, звучит ли это разумно, если они так похожи?

Jeremy Lakeman
9 августа 2021 в 01:57
0

Не пытайтесь сделать схему слишком гибкой, просто постарайтесь соответствовать сегодняшним требованиям. ЯГНИ. Если вы используете таблицу на уровне наследования, вы можете добавить необязательные столбцы базы данных, которые сопоставляются только с одним подклассом. Должны ли теги быть перечислением? Вы действительно хотите перекомпилировать, когда клиент хочет новое имя тега?

Jonathon Chase
9 августа 2021 в 02:40
0

Каково определение MenuItemEstablishment?

Jonathon Chase
9 августа 2021 в 03:20
0

По сути, если MenuItemEstablishment не наследует напрямую от VeganItemEstablishment<MenuItem, Restaurant>, вы сталкиваетесь с желанием иметь ковариантный универсальный тип в ситуации, когда ваши универсальные типы инвариантны. Если какой-либо из параметров универсального типа для VeganItemEstablishment в большей или меньшей степени является производным от MenuItem или Restaurant, он не соответствует определению инварианта и не будет разрешен.

BeniaminoBaggins
9 августа 2021 в 04:10
0

@JeremyLakeman У меня возникли проблемы с избавлением от некоторых ненужных подклассов. Как получить две таблицы одного типа? У меня есть 2 таблицы, содержащие tags типа GroceryItemTag и MenuItemTag. У них в основном есть 3 поля, одно из которых было перечислением. Я создал новый класс с именем Option, где предыдущее перечисление теперь представляет собой просто int, но мне нужна таблица с именами MenuItemTags и GroceryItemTags, оба типа Option.

Jeremy Lakeman
9 августа 2021 в 04:20
0

Если вы собираетесь упростить схему, напишите sql-скрипт миграции для перемещения данных.

BeniaminoBaggins
9 августа 2021 в 04:25
0

@JeremyLakeman Спасибо, я просто удалил таблицы и создал новую миграцию (приложение еще не запущено). Но я все еще получаю: начальный объект для типа объекта «Option» не может быть добавлен, потому что другой начальный объект со значением ключа «Id: 0» уже добавлен. Я думаю, это новый вопрос :)

Ответы (0)