Entity Framework сгенерировала имена для многих-многих отношений [duplicate]

, если explode используется вместе с foreach для создания новой строки, вы можете имитировать взрыв, используя цикл while следующим образом:

CREATE FUNCTION explode_and_loop(sep VARCHAR(),inputstring VARCHAR()) RETURNS VARCHAR() 
BEGIN
    DECLARE part,returnstring VARCHAR();
    DECLARE cnt,partsCnt INT();
    SET returnstring = '';
    SET partsCnt = ((LENGTH(inputstring ) - LENGTH(REPLACE(inputstring,sep,''))) DIV LENGTH(sep);
    SET cnt = 0;
    WHILE cnt <= partsCnt DO
        SET cnt = cnt + 1;
        SET part = SUBSTRING_INDEX(SUBSTRING_INDEX(inputstring ,sep,cnt),sep,-1);
        -- DO SOMETHING with the part eg make html:
        SET returnstring = CONCAT(returnstring,'<li>',part,'</li>')
    END WHILE;
    RETURN returnstring;
END

этот пример вернет html-список частей. (требуются переменные legths должны быть добавлены)

24
задан BlackICE 21 May 2013 в 14:22
поделиться

4 ответа

modelBuilder.Entity<Account>()
            .HasMany(a => a.Products)
            .WithMany()
            .Map(x =>
            {
                x.MapLeftKey("Account_Id");
                x.MapRightKey("Product_Id");
                x.ToTable("AccountProducts");
            });
57
ответ дан Ali Seyedi 17 August 2018 в 18:04
поделиться
  • 1
    Спасибо за это. Отметьте это как принятый ответ, так как это позволяет мне настроить однонаправленную связь без необходимости добавлять (ненужную) ассоциацию в классе Product – Fixer 19 January 2012 в 16:30
  • 2
    Что делать, если я хочу следить за дополнительными данными в таблице корреляции, такими как date_added, тип отношения и т. Д. Могу ли я определить POCO для AccountProducts? И как бы вы сделали сопоставление в этом случае? – hazimdikenli 9 February 2013 в 17:57
  • 3
    Это сработало для меня, но только после того, как я добавил эквивалент p => p.Accounts внутри .WithMany(). Не делая этого, это создавало странное свойство внутри Учетных записей. – Chris 19 February 2014 в 03:26
  • 4
    Я не уверен, что это ожидаемое поведение или нет, но в моем случае мой public virtual ICollection<Product> Products { get; set; } удаляет дубликаты. Так что, если в (1, 1) есть 2 строки с (Account_ID, Product_ID), мой Products collection.ToList () содержит только одну запись с идентификатором 1 – mmcrae 21 December 2015 в 02:40
  • 5
    @ Крис без этого случайного комментария, и я, случайно прочитав его, я бы совсем застрял. Спасибо! – mmcrae 21 December 2015 в 02:53
        public AccountProductsMap()
    {
        this.ToTable("AccountProducts");
        this.HasKey(cr => cr.Id);

        this.HasMany(cr => cr.Account)
            .WithMany(c => c.Products)
            .Map(m => m.ToTable("AccountProducts_Mapping"));
    }
1
ответ дан andre 17 August 2018 в 18:04
поделиться

Сначала код создает таблицы в правильном реляционном порядке. Когда

У одной учетной записи может быть много продуктов.

Таблица продуктов должна хранить ключ для своей учетной записи, как это сейчас происходит.

То, что вы пытаетесь увидеть в db, - это отношения «многие ко многим», а не одно. Если вы хотите добиться этого с помощью кода сначала, вы должны перепроектировать свои сущности

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Account> Accounts { get; set; }
}

class Account
{        
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

. В этом случае у одного продукта может быть много учетных записей, а одна учетная запись может иметь много продуктов.

2
ответ дан archil 17 August 2018 в 18:04
поделиться

Что предлагает EF, это отношение «один ко многим».

Одна учетная запись может иметь много продуктов, то есть каждый продукт имеет Account_Id

. Если вы хотите, чтобы многие из многих (и создать промежуточную таблицу), следует работать

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Account> Accounts { get; set; }
}

class Account
{        
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}
6
ответ дан NinjaNye 17 August 2018 в 18:04
поделиться
  • 1
    О, это было легко. Но зачем нам нужна двунаправленная ассоциация? В модели домена мы не хотим получать доступ к учетным записям через каждый продукт. – Fixer 19 January 2012 в 16:14
  • 2
    Если продукт не знает, к какой учетной записи он привязан, нет способа определить отношения. Например, если вы используете viewModels, вы всегда можете исключить учетную запись и отображать только данные, которые вам нужны – NinjaNye 19 January 2012 в 16:17
  • 3
    Вы знаете какой-либо способ скрыть (модификатор доступа?) Двунаправленную связь? – Fixer 19 January 2012 в 16:23
  • 4
    См. Мой комментарий выше. В вашем объекте viewModel или DTO или независимо от того, что вы используете, исключите AccountId из сопоставлений, тогда он будет скрыт для всех, кто использует ваш класс. Если вы хотите удалить его из db, это невозможно. База данных должна иметь этот столбец для определения отношений – NinjaNye 19 January 2012 в 16:26
  • 5
    @NinjaNye Что мне делать, если мне нужно определить отдельный ключ для таблицы соединения? – Geethanga 13 February 2013 в 12:23
Другие вопросы по тегам:

Похожие вопросы: