流畅的 nhibernate 自动映射域难点

发布于 2024-11-01 19:04:10 字数 1631 浏览 3 评论 0 原文

试图让我了解自动映射。我在尝试自动映射我的域并生成数据库时遇到问题。我确信这很简单,我做错了。

问题是,生成了正确的表,但生成的表中仅存在基类中的 ID 字段,实体中没有生成任何其他字段。

BaseEntity 与实体位于不同的命名空间中。

我不知道从这里去哪里,有什么想法吗?

这是我的映射配置:

public static ISessionFactory CreateSessionFactory()
{
  return _sessionFactory = Fluently.Configure()
    .Database(ConfigureDatabase())
    .Mappings(m => m.AutoMappings.Add(CreateMappings()))
    .ExposeConfiguration(BuildSchema)
    .BuildSessionFactory();
}

private static IPersistenceConfigurer ConfigureDatabase()
{
  return MsSqlConfiguration
    .MsSql2008.ShowSql()
    .ConnectionString(c => c.FromAppSetting("MSSqlConnectionString"))
    .ProxyFactoryFactory<ProxyFactoryFactory>();
}

private static AutoPersistenceModel CreateMappings()
{
  return AutoMap.AssemblyOf<Organisation>(new AutomappingConfig())
    .Conventions.Add<CascadeConvention>();
}

private static void BuildSchema(Configuration config)
{
  new SchemaUpdate(config)
    .Execute(false,true);
}

这是我的 autoMappingConfig

public class AutomappingConfig : DefaultAutomappingConfiguration
{
  public override bool ShouldMap(Type type)
  {
    return type.Namespace == "Domain.Model" && type.IsClass;
  }
}

我的所有实体都继承这个基类:

public class BaseEntity<T> where T : BaseEntity<T>
{
  public virtual int Id { get; set; }
}

还有一个示例实体:

public class Contact : BaseEntity<Contact>, IAggregateRoot
{
  public virtual String Name { get; set; }
  public virtual Organisation Organisation { get; set; }
}

Trying to get my head round automapping. I am having a problem when trying to automap my domain and generate the database. Im sure its something simple im doing wrong.

The problem is, the correct tables are generated, but only the ID field from the base class is present within the generated tables, none of the other fields within the entities are generated.

BaseEntity is in a different namespace to the entities.

Im not sure where to go from here, any ideas?

Here is my mapping configuration:

public static ISessionFactory CreateSessionFactory()
{
  return _sessionFactory = Fluently.Configure()
    .Database(ConfigureDatabase())
    .Mappings(m => m.AutoMappings.Add(CreateMappings()))
    .ExposeConfiguration(BuildSchema)
    .BuildSessionFactory();
}

private static IPersistenceConfigurer ConfigureDatabase()
{
  return MsSqlConfiguration
    .MsSql2008.ShowSql()
    .ConnectionString(c => c.FromAppSetting("MSSqlConnectionString"))
    .ProxyFactoryFactory<ProxyFactoryFactory>();
}

private static AutoPersistenceModel CreateMappings()
{
  return AutoMap.AssemblyOf<Organisation>(new AutomappingConfig())
    .Conventions.Add<CascadeConvention>();
}

private static void BuildSchema(Configuration config)
{
  new SchemaUpdate(config)
    .Execute(false,true);
}

Heres my autoMappingConfig

public class AutomappingConfig : DefaultAutomappingConfiguration
{
  public override bool ShouldMap(Type type)
  {
    return type.Namespace == "Domain.Model" && type.IsClass;
  }
}

And all of my entities inherit this base class:

public class BaseEntity<T> where T : BaseEntity<T>
{
  public virtual int Id { get; set; }
}

And an example entity:

public class Contact : BaseEntity<Contact>, IAggregateRoot
{
  public virtual String Name { get; set; }
  public virtual Organisation Organisation { get; set; }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

埋情葬爱 2024-11-08 19:04:10

BaseEntity 与实体位于不同的命名空间中。

您可能想要做的就是尝试将它们放在同一个命名空间中。另外,您可能想注释掉上面的检查:

return type.Namespace == "Domain.Model" && type.IsClass;

上面的语句可能是导致您只映射基类的原因。您的基类位于哪个命名空间以及您的示例实体之一位于哪个命名空间?

当我遇到这样的问题时,我会尝试简化事情,直到找出导致问题的原因。

编辑:

经过进一步研究,我认为您需要使用以下内容:

.IgnoreBase(typeof(BaseEntity<>));  

因此您上面的代码将更改为:

private static AutoPersistenceModel CreateMappings()
{
  return AutoMap.AssemblyOf<Organisation>(new AutomappingConfig())
    .Conventions.Add<CascadeConvention>()
    .IgnoreBase(typeof(BaseEntity<>));
}

这是摘自 FNH 维基

我们添加了 IgnoreBase
调用它只是指示
自动映射器忽略实体类;
您可以多次链接此调用
根据需要。

通过此更改,我们现在得到了
所需的映射。实体被忽略为
就Fluent NHibernate而言,
和所有属性(Id 在我们的
情况)被视为就好像它们在
具体子类。

BaseEntity is in a different namespace to the entities.

What you may want to do is try putting them in the same namespace. Also you may want to comment out the check you have above:

return type.Namespace == "Domain.Model" && type.IsClass;

The above statement may be what is causing you to only map your base classes. What namespace is your base class in and what namespace are one of your example entities in?

When I run into problems like this I try to simplify things until I find out what is causing my issues.

Edit:

After further research I think you need to use the following:

.IgnoreBase(typeof(BaseEntity<>));  

So your code above would be changed to:

private static AutoPersistenceModel CreateMappings()
{
  return AutoMap.AssemblyOf<Organisation>(new AutomappingConfig())
    .Conventions.Add<CascadeConvention>()
    .IgnoreBase(typeof(BaseEntity<>));
}

This is an excerpt taken from the FNH Wiki:

We've added the IgnoreBase
call which simply instructs the
automapper to ignore the Entity class;
you can chain this call as many times
as needed.

With this change, we now get our
desired mapping. Entity is ignored as
far is Fluent NHibernate is concerned,
and all the properties (Id in our
case) are treated as if they were on
the specific subclasses.

天涯沦落人 2024-11-08 19:04:10

来自自动映射:基类型作为继承策略

抽象基类

你会注意到我们的实体类是
抽象的。这是很好的做法,但是
郑重声明,这不是强制性的。
如果您遇到问题,那就是
不太可能是这样。

如果您想知道,请制作
类摘要就像是在说“我会
从不直接创建这个,而是我
将创建派生类,例如
客户和订单(继承自
实体)。”

默认行为是考虑
抽象类作为层超类型
并且有效地未映射,您可能想要
针对特定场景更改此设置。
最简单的方法是使用
IncludeBase,其中 T 是您的
实体。

AutoMap.AssemblyOf<Entity>(cfg)
  .IncludeBase<BaseEntity>();

AutoMap.AssemblyOf<Entity>(cfg)
  .IncludeBase(typeof(BaseEntity<>));

文章:自动映射通用基类

From Automapping: base-type as an inheritance strategy:

Abstract base-classes

You'll notice that our Entity class is
abstract. This is good practice, but
for the record, it is not mandatory.
If you're experiencing problems, it's
unlikely to be this.

In case you're wondering, making the
class abstract is like saying "I'll
never create this directly, instead I
will create derived classes such as
Customer and Order (which inherit from
Entity)."

The default behavior is to consider
abstract classes as layer supertypes
and effectively unmapped, you may want
to change this for specific scenarios.
The easiest way to do this is to use
IncludeBase, where T is your
entity.

AutoMap.AssemblyOf<Entity>(cfg)
  .IncludeBase<BaseEntity>();

AutoMap.AssemblyOf<Entity>(cfg)
  .IncludeBase(typeof(BaseEntity<>));

Article: Auto-mapping generic base classes

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文