简体   繁体   English

流利的NHibernate:基类的ISet

[英]Fluent NHibernate: ISet of base class

In my project I have a base class (not mapped): 在我的项目中,我有一个基类(未映射):

public abstract class BaseEntity
{
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
}

Also I have a few inherited classes (they look all almost the same, so here is a code and map for only one) 我也有一些继承的类(它们看起来几乎都一​​样,所以这是仅一个的代码和映射)

public class User : BaseEntity
{
    public virtual int UserId { get; set; }
    public virtual string Login { get; set;  }
    public virtual string PasswordHash { get; set; }

    public virtual ISet<BaseEntity> Entities { get; set; }
}

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        this.Id(x => x.UserId);
        this.Map(x => x.Login);
        this.Map(x => x.PasswordHash);
        this.HasManyToMany<BaseEntity>(x => x.Entities);
    }
}

Next, I have a NHibernateHelper: 接下来,我有一个NHibernateHelper:

public class NHibernateHelper
{
    public static ISession OpenSession()
    {
        ISessionFactory sessionFactory = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2008.ConnectionString(@"someconstring")
            .ShowSql()
        )
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<User>())

        .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true))

        .BuildSessionFactory();
        return sessionFactory.OpenSession();
    }
}

And here is a question: 这是一个问题:

How can I exclude BaseEntity class from mapping, if I need table like EnitiyToEntity in my Database for many-to-many relationship? 如果我需要数据库中的表EnitiyToEntity这样的多对多关系,如何从映射中排除BaseEntity类?

Take a look to this: https://www.codeproject.com/Articles/232034/Inheritance-mapping-strategies-in-Fluent-Nhibernat 看看这个: https : //www.codeproject.com/Articles/232034/Inheritance-mapping-strategies-in-Fluent-Nhibernat

If I understand your question the solution should be to implement TPC (Table per concrete class). 如果我理解您的问题,解决方案应该是实现TPC(每个具体类的表)。

By the way, in your mapping you have to use the concrete type for HasManyToMany . 顺便说一句,在映射中,您必须为HasManyToMany使用具体类型。

For example (I supposed your user is referenced to many groups): 例如(我假设您的用户被引用到许多组):

 HasManyToMany<Group>(x => x.Entities).Table("UsersGroups");

where the Group class is something like this: Group类是这样的:

    public class Group : BaseEntity
    {
        public virtual int GroupId { get; set; }
        public virtual string PasswordHash { get; set; }
        public virtual ISet<BaseEntity> Members { get; set; }
    }

And in the GroupMap class you can reference the users like this: 在GroupMap类中,您可以像这样引用用户:

  HasManyToMany<User>(x => x.Members).Table("UsersGroups");

If you reference a class you have to map it. 如果引用一个类,则必须对其进行映射。 So map Entity as ClassMap and all the others as SubclassMap. 因此,将Entity映射为ClassMap,将所有其他映射为SubclassMap。 They will end up as union subclass which is one table per class. 它们最终将成为并集子类,每个类一个表。 Unfortunatly you can not map a hasmanytoany with FNH. 不幸的是,您无法使用FNH映射hasmanytoany。 You can map it as hasmanytomany and work around it: 您可以将其映射为hasmanytomany并解决它:

    var config = new Configuration();

    config.BeforeBindMapping += BeforeBindMapping;
    _config = Fluently
        .Configure(config)
        ...

    private void BeforeBindMapping(object sender, NHCfg.BindMappingEventArgs e)
    {
        var userclass = e.Mapping.RootClasses.FirstOrDefault(rc => rc.name.StartsWith(typeof(User).FullName));
        if (userclass != null)
        {
            HbmSet prop = (HbmSet)paymentclass.Properties.FirstOrDefault(rc => rc.Name == "Entities");
            prop.Item = new HbmManyToAny // == prop.ElementRelationship
            {
                column = new[]
                    {
                        new HbmColumn { name = "entityType", notnull = true, notnullSpecified = true },
                        new HbmColumn { name = "entity_id", notnull = true, notnullSpecified = true }
                    },
                idtype = "Int64",
                metatype = "String",
                metavalue = typeof(Entity).Assembly.GetTypes()
                    .Where(t => !t.IsInterface && !t.IsAbstract && typeof(Entity).IsAssignableFrom(t))
                    .Select(t => new HbmMetaValue { @class = t.AssemblyQualifiedName, value = t.Name })
                    .ToArray()
            };
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM