Использование дискриминатора с Fluent NHibernate - PullRequest
4 голосов
/ 31 июля 2011

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

Вот мой код:

public class Item
{
    public virtual int Id { get; set; }
    public virtual Status ItemStatus { get; set; }
}

public abstract class Status
{
    private readonly int _id;
    public static readonly Status Foo = new FooStatus(1);
    public static readonly Status Bar = new BarStatus(2);

    public Status()
    {

    }

    protected Status(int id)
    {
        _id = id;
    }

    public virtual int Id { get { return _id; } }
    public abstract string Name { get; }
    public abstract string BackgroundColor { get; }
}

public class FooStatus : Status
{
    public FooStatus()
    {

    }

    public FooStatus(int id)
        : base(id)
    {

    }

    public override string Name
    {
        get { return "Foo Status"; }
    }

    public override string BackgroundColor
    {
        get { return "White"; }
    }
}

public class BarStatus : Status
{
    public BarStatus()
    {

    }

    public BarStatus(int id)
        : base(id)
    {

    }

    public override string Name
    {
        get { return "Bar Status"; }
    }

    public override string BackgroundColor
    {
        get { return "Black"; }
    }
}

А вот мое отображение:

public class ItemMap : ClassMap<Item>
{
    public ItemMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();

        DiscriminateSubClassesOnColumn<int>("ItemStatus", 0).AlwaysSelectWithValue();
    }
}

По сути, что я хотел быв том, что если я установлю ItemStatus на Status.Foo, то столбец ItemStatus будет иметь значение 1. То, что я сейчас имею, не выдает никаких исключений, но всегда вставляет ItemStatus как 0.

Это код для вставки, который я использую:

        using (var session = sessionFactory.OpenSession())
        using (var transaction = session.BeginTransaction())
        {
            var item = new Item
                           {
                               ItemStatus = Status.Foo
                           };
            session.Save(item);
            transaction.Commit();

            var firstItem = session.Get<Item>(1);
            Console.WriteLine(firstItem.ItemStatus.Name);
        }

Где я могу прочитать эту тему, используя FNH?

Прежде чем кто-либо предложит проверить в Google, я выполнил поискнесколько вещей, но я не могу найти полный пример.

Ответы [ 3 ]

3 голосов
/ 31 июля 2011

Ваш SubclassMap будет выглядеть примерно так:

public class FooStatusMap : SubclassMap<FooStatus>
{
    public FooStatusMap()
    {
        DiscriminatorValue(1);
    }
}

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

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

0 голосов
/ 11 октября 2011

Если вы открыты для столбца Discriminator с именами классов производных классов, вы можете реализовать это с помощью автоматического преобразования.

В вашей фабрике сессий:

private static ISessionFactory CreateSessionFactory()
{
    var cfg = new MyMappingConfiguration();
    return Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("MyConnectionKey")).FormatSql().ShowSql()
            )
    .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Status>(cfg)
    .IncludeBase<Status>()
    .Conventions.Add<PrimaryKeyConvention>()))
    .BuildSessionFactory();
}

Затем добавьте переопределение MyMappingConfiguration:

public class MappingConfiguration : DefaultAutomappingConfiguration
{
    public override bool IsId(Member member)
    {
        return member.Name == member.DeclaringType.Name + "Id";
    }

    public override bool IsDiscriminated(Type type)
    {
        return true;
    }
}

Надеюсь, что ч

0 голосов
/ 31 июля 2011

Я бы не писал подкарты для всех подклассов, вы можете просто сделать это вместо этого

public class FooMap: ClassMap<T>
{
//other mapping
DiscriminateSubClassesOnColumn("DiscriminatorColumn")
.SubClass<Foo1>(m => { })
.SubClass<Foo2>(m => { })
.SubClass<Foo3>(m => { });
}

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...