Программирование к интерфейсам при отображении с Быстрым NHibernate

Учитывая, что входы a и b будут строками. Приведенный ниже код должен дать вам желаемый результат.

var result = string.Join("", b.ToString().Select((x, i) => (i % 2) == 0 || a.ToString().Length <= i ? x.ToString() : a.ToString().Substring(i, 1)));

этот код будет учитывать разницу в длине.

Редактировать : Вы также можете использовать LINQ, избегая циклов и рассматривая a и b как числа, как показано ниже.

int[] ai = a.ToString().Select(x => int.Parse(x.ToString())).ToArray();
int[] bi = b.ToString().Select(x => int.Parse(x.ToString())).ToArray();

var number1 = string.Join("", bi.Select((x, i) => (i % 2) == 0 || ai.Count() <= i ? x.ToString() : ai[i].ToString()));
var number2 = string.Join("", ai.Select((x, i) => (i % 2) == 0 || bi.Count() <= i ? x.ToString() : bi[i].ToString()));

Console.WriteLine("Array 1:" + Convert.ToInt32(number1));
Console.WriteLine("Array 2:" + Convert.ToInt32(number2));
25
задан Rune Jacobsen 10 May 2009 в 17:44
поделиться

5 ответов

ОБНОВЛЕНИЕ: с использованием union-subclass не поддерживается через свободный интерфейс, предоставляемый fluent-nhibernate. Вам придется использовать обычный файл сопоставления hbm и добавить его.

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

По сути, вы создаете определение отображения для базового класса (в данном случае вашего интерфейса) и указываете, как NHibernate должен иметь дело с разработчиками с помощью подкласса union.

Так, например, это должно позволить вам создавать полиморфные ассоциации:

<class name="IAccountManager"
                abstract="true"
                table="IAccountManager">

        <id name="Id">
                <generator class="hilo"/>
        </id>

        <union-subclass
                table="DefaultAccountManager"
                name="DefaultAccountManager">
                <property name="FirstName"/>
        </union-subclass>

        <union-subclass
                table="AnotherAccountManagerImplementation"
                name="AnotherAccountManagerImplementation">
                <property name="FirstName"/>
        </union-subclass>
        ...
</class> 

Обратите внимание, что Id одинаков для всех конкретных разработчиков. NHibernate требовал этого. Кроме того, таблицы IAccountManager на самом деле не существует.

Вы также можете попробовать применить неявный полиморфизм NHibernate (описанный ниже стратегии «таблица на конкретный класс») - но он имеет массу ограничений.

8
ответ дан 28 November 2019 в 21:06
поделиться

Я понимаю, что это отвлекающий маневр, а не ответ на ваш вопрос (хотя я думаю, что у mookid это есть).

Вам действительно следует оценить, действительно ли интерфейсы в ваших доменных объектах предоставление чего-либо стоящего; редко можно встретить ситуацию, в которой вам действительно нужно это сделать.

Например: Как полагаться на IMessage менее взаимосвязано, чем полагаться на Сообщение , когда они оба (почти ) несомненно одинаковые подписи? Вам не нужно издеваться над сущностью, потому что у нее редко бывает достаточно поведения, чтобы требовать издевательства.

12
ответ дан 28 November 2019 в 21:06
поделиться

Вы можете настроить свой интерфейс так, чтобы он содержал только геттер:

public interface ISomeEntity
{
    int Id { get; }
}

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

Если вы хотите запретить установку идентификатора, даже если вы держите ссылку на конкретный экземпляр, вы можете воздержаться от реализации установщика, а затем позволить NHibernate получить доступ к полю вместо свойства - это верно, NHibernate может использовать изящный трюк с отражением, чтобы установить поле идентификатора напрямую вместо вызова свойства. Затем вы можете сопоставить идентификатор следующим образом:

Id(e => e.Id).Access.AsCamelCaseField();

, и в этом случае ваше свойство Id должно поддерживаться соответствующим полем id . Существуют другие соглашения об именах, например, если вы предпочитаете подчеркивание в качестве префикса закрытого поля.

10
ответ дан 28 November 2019 в 21:06
поделиться

I am having exactly the same issue. К сожалению, у меня есть веская причина для использования интерфейсов сущностей; модель сущности будет реализована по-разному и с разными сопоставлениями для каждого клиента.

Вся модель должна быть доступна только для чтения, поэтому интерфейсы имеют стиль:

public interface IAccount
{
    long AccountId { get; }
    IHouse House { get; }
}

public interface IHouse
{
    long HouseId { get; }
    HouseStatus Status { get; }
    IList<IAccount> Accounts { get; }
}

Конкретные реализации затем реализуют их с помощью внутренних установщиков:

public class Account: IAccount
{
    public virtual long AccountId { get; internal set; }
    public virtual IHouse House { get; internal set; }
}

public class House: IHouse
{
    public virtual long HouseId { get; internal set; }
    public virtual HouseStatus Status { get; internal set; }
    public virtual IList<IAccount> Accounts { get; internal set; }
}

] Я пошел по пути сопоставления с конкретными классами. Все в порядке, пока вы не создадите отношения, которые возвращают интерфейсы и должны быть преобразованы в конкретные реализации.

HasMany(x => x.Accounts)

может стать

HasMany<Account>(x => x.Accounts)

Но не существует эквивалентного «преобразования» для

References(x => x.House)

Отображение на интерфейсы (более аккуратное решение) подбрасывает проблема, упомянутая выше, в том, что идентификатор должен существовать в самом верхнем классе для настройки и требует установщика на интерфейсе.

public sealed class AccountMap : ClassMap<IAccount>
{
    public PokerPlayerMap()
    {
        Id(x => x.AccountId, "account_id");

        DiscriminateSubClassesOnColumn("Type").SubClass<Account>(s =>  
        {
            References(x => x.House);       
        });
    }
}

На данный момент моим единственным решением является добавление установщиков ко всем полям идентификатора интерфейса. Жаль, что Id не может существовать внутри подкласса или иметь приведенный тип из интерфейса.

10
ответ дан 28 November 2019 в 21:06
поделиться

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

Ссылки теперь имеют общую перегрузку, позволяющую использовать каст, который искал Геккон в своем ответе.

4
ответ дан 28 November 2019 в 21:06
поделиться
Другие вопросы по тегам:

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