Unable to cast 'NHibernate.Collection.Generic.PersistentGenericSet`1 to System.Collections.Generic.IList`1

已查看 2,808 次
跳至第一个未读帖子

Riderman Sousa

未读,
2013年5月24日 16:12:552013/5/24
收件人 Fluent NHibernate Group

I have a domain class:


public class Agencia : IEntity
{
    public virtual int Id { get; set; }

    public virtual string Nome { get; set; }

    public virtual string Identificacao { get; set; }

    public virtual IList<Pessoa> Gerentes { get; protected set; }

    public Agencia()
    {
        Gerentes = new List<Pessoa>();
    }

    public virtual void AddGerente(Pessoa gerente)
    {
        Gerentes.Add(gerente);
    }
    public virtual void AddGerentes(params Pessoa[] gerentes)
    {
        Parallel.ForEach(gerentes, (pessoa) => Gerentes.Add(pessoa));
    }
}

public class Pessoa: IEntity
{
    public virtual int Id { get; set; }

    public virtual string Nome { get; set; }

}

With this convention (defined as set AsSet)

public class AgenciaConvention : IAutoMappingOverride<Agencia>
{
    public void Override(AutoMapping<Agencia> mapping)
    {
        mapping.HasManyToMany(a => a.Gerentes).Cascade.AllDeleteOrphan().AsSet().Not.Inverse();
    }
}

When I run this test:


[TestMethod]
[Description("Uma agência tem vários gerêntes")]
public void AgenciaTemVariosGerentes()
{
    // Arrange
    var fix = new Fixture();
    var currentUser = GetLoggedUser();

    // Create a List<Pessoa>

    var gerentes = fix.Build<Pessoa>()
                        .With(p => p.Nome)
                        .With(p => p.CPF)
                        .With(p => p.CreateBy, currentUser)
                        .OmitAutoProperties()
                        .CreateMany<Pessoa>(10).ToList();

    // Action

    new PersistenceSpecification<Agencia>(Session)
            .CheckProperty(p => p.Nome, fix.Create<string>().Truncate(80))
            .CheckProperty(p => p.Identificacao, fix.Create<string>().Truncate(10))
            .CheckReference(p => p.Regional,
                fix.Build<Regional>()
                    .With(p => p.Nome)
                    .OmitAutoProperties()
                    .Create()
            , new IDEqualityComparer())
            .CheckList(p => p.Gerentes, gerentes, new IDEqualityComparer())
            .CheckReference(p => p.CreateBy, currentUser, new IDEqualityComparer())
            .VerifyTheMappings(); // Assert
}

How can I test this list?

The collection should be AsSet, it necessary that the Parent and Children fields are PK, FK

Error:


Test Name: AgenciaTemVariosGerentes
Test FullName: {OMMITED}.Integration.Test.AgenciaTest.AgenciaTemVariosGerentes
Test Source: {OMMITED}.Integration.Test\AgenciaTest.cs : line 22
Test Outcome: Failed
Test Duration: 0:00:02,4093555

Result Message:
Test method {OMMITED}.Integration.Test.AgenciaTest.AgenciaTemVariosGerentes threw exception: 
NHibernate.PropertyAccessException: Invalid Cast (check your mapping for property type mismatches); setter of CreditoImobiliarioBB.Model.Regional ---> System.InvalidCastException: Unable to cast object of type 'NHibernate.Collection.Generic.PersistentGenericSet`1[CreditoImobiliarioBB.Model.Pessoa]' to type 'System.Collections.Generic.IList`1[CreditoImobiliarioBB.Model.Pessoa]'.
Result StackTrace:
at (Object , Object[] , SetterCallback )
   at NHibernate.Bytecode.Lightweight.AccessOptimizer.SetPropertyValues(Object target, Object[] values)
   at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)
 --- End of inner exception stack trace ---
    at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)
   at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValues(Object entity, Object[] values)
   at NHibernate.Persister.Entity.AbstractEntityPersister.SetPropertyValues(Object obj, Object[] values, EntityMode entityMode)
   at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
   at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
   at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
   at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
   at NHibernate.Impl.SessionImpl.Save(Object obj)
   at FluentNHibernate.Testing.PersistenceSpecification`1.TransactionalSave(Object propertyValue)
   at FluentNHibernate.Testing.Values.ReferenceProperty`2.HasRegistered(PersistenceSpecification`1 specification)
   at FluentNHibernate.Testing.PersistenceSpecification`1.RegisterCheckedProperty(Property`1 property, IEqualityComparer equalityComparer)
   at FluentNHibernate.Testing.PersistenceSpecificationExtensions.CheckReference[T](PersistenceSpecification`1 spec, Expression`1 expression, Object propertyValue, IEqualityComparer propertyComparer)
   at CreditoImobiliarioBB.Repository.Integration.Test.AgenciaTest.AgenciaTemVariosGerentes() in {OMMITED}.Integration.Test\AgenciaTest.cs:line 27

Thanks.

Riderman de Sousa Barbosa

Web Developer | MCPD Certify

Skype.: 4042-6002 | Cel.: (31) 8681-1986

bindsolution.com

Microsoft Parner Network

Carl Bussema

未读,
2013年5月24日 16:24:332013/5/24
收件人 fluent-n...@googlegroups.com
If you're mapping as a set, you need to use Iesi.Collections.Generic.ISet<T> as the object type in your domain (implemented by HashedSet<T> normally).



--
You received this message because you are subscribed to the Google Groups "Fluent NHibernate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fluent-nhibern...@googlegroups.com.
To post to this group, send email to fluent-n...@googlegroups.com.
Visit this group at http://groups.google.com/group/fluent-nhibernate?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Riderman Sousa

未读,
2013年5月24日 17:07:062013/5/24
收件人 Fluent NHibernate Group
I do not want to create a new dependency in my domain. Because if I have to migrate ORM this can be a problem.

Is there any way to accomplish this without creating a dependency?

Riderman Sousa

未读,
2013年5月24日 19:14:362013/5/24
收件人 Fluent NHibernate Group

Even after installing the package via nuget Iesi.Collections I can not set my collection as ISet <>;


Inline image 1

Inline image 2
image.png
image.png

Oskar Berggren

未读,
2013年5月25日 05:25:552013/5/25
收件人 fluent-n...@googlegroups.com
You have download iesi.collections 4.0 which is for use with .Net 4 (where ISet is builtin) and the future NHibernate 4.0.

You should use the iesi.collections included with your copy of NHibernate.

/Oskar


2013/5/25 Riderman Sousa <rider...@bindsolution.com>
image.png
image.png

Oskar Berggren

未读,
2013年5月25日 05:27:022013/5/25
收件人 fluent-n...@googlegroups.com
If you get (a recent) NHibernate via Nuget it should resolve to the correct Iesi dependency automatically.

/Oskar



2013/5/25 Oskar Berggren <oskar.b...@gmail.com>
image.png
image.png

Riderman Sousa

未读,
2013年5月27日 08:29:212013/5/27
收件人 Fluent NHibernate Group

ISet not in Iesi.Collections.dll, or has some dependency with NHibernate.
I can not install NHibernate on my domain layer!

Anyway, I found the solution).

Thanks.


Riderman de Sousa Barbosa

Web Developer | MCPD Certify

Skype.: 4042-6002 | Cel.: (31) 8681-1986

bindsolution.com

Microsoft Parner Network

image.png
image.png

Oskar Berggren

未读,
2013年5月27日 08:41:532013/5/27
收件人 fluent-n...@googlegroups.com
Not sure what you mean, bug nuget NHibernate 3.3.3 (http://nuget.org/packages/NHibernate/3.3.3.4000) definitely depends on Iesi.Collections 3.x (which include ISet).  If you have a nuget NHibernate package older than 3.3.2 it might install the wrong Iesi.Collections version (but then NHibernate won't run at all).

If you downloaded NHibernate binaries from sourceforge, the package includes the Iesi.Collections library.

In either case, if you had a version of NHibernate running, the Iesi.Collections library should have already been there, since NHibernate won't run without it.

/Oskar



2013/5/27 Riderman Sousa <rider...@bindsolution.com>
image.png
image.png

Riderman Sousa

未读,
2013年5月27日 12:26:252013/5/27
收件人 Fluent NHibernate Group

Yes, I tried installing just the Iesi.Collections) in my domain layer (without installing NHibernate).

I did not want to have the ORM as dependency in my domain layer;

I do not know why, but when I installed Iesi.Collection could not use ISet.
Anyway, I do not have but need since ICollection can be used in its place!

image.png
image.png

Carl Bussema

未读,
2013年5月27日 12:45:292013/5/27
收件人 fluent-n...@googlegroups.com

Icollection will not enforce uniqueness. You will need to have your domain do that or risk exceptions.

image.png
image.png

Riderman Sousa

未读,
2013年5月27日 13:38:342013/5/27
收件人 Fluent NHibernate Group
Carl, I do not see much problems with that.

What guarantees the uniqueness is the `Id` of an entity.
Once access to the Id property is protected, and the database has one constraint (unique/pk) I do not see how it could generate exceptions;

How do you usually work?
In my case, Id is generated by database and the Id property is as protected.



image.png
image.png

Carl Bussema

未读,
2013年5月27日 14:11:132013/5/27
收件人 fluent-n...@googlegroups.com

If you add the same item to the collection multiple times, nh will try to add the relationship twice. This may violate pk or unique key constraints. Look at the documentation for set vs bag vs list.

image.png
image.png

Riderman Sousa

未读,
2013年5月27日 18:07:362013/5/27
收件人 Fluent NHibernate Group

I see, interesting.

But I really do not see many benefits in using Iese.Collections, because even if you try to add the same item multiple times in a collection or will generate an exception Database or CLR.
Anyway add the same item twice should and will generate an exception.

But I agree with you that as soon thrown as the exception is better. In this case, it would be better to throw exception on server level first.

Anyway, the collections on my app are of type) ICollection<> and by convention AsSet Are initialized with HashSet<>

NHibernate as a dependency in my domain layer is a break designer in my app, I do not see many options.



image.png
image.png

Alexander I. Zaytsev

未读,
2013年5月27日 18:18:162013/5/27
收件人 fluent-n...@googlegroups.com
Hi there,

The problem there that NHibernate was here a long time before Microsoft introduced ISet<>/HashSet to BCL. So Iesi.Collection has been written to cover lack of sets.

If you do want to use System.Collections.Generic.ISet<> and System.Collections.Generic.HashSet<> instead of Iesi you need to take a look over http://nuget.org/packages/NHibernate.SetForNet4/ package.

But anyway Iesi.Collections should be installed because NHibenate has dependencies on it.

Regards,
Alex
image.png
image.png
回复全部
回复作者
转发
0 个新帖子