简体   繁体   中英

Nhibernate: how to add AddAll method for 'Sets'?

Since I installed current version of Nhibernate (version 4.0.0.4000) Iesi.Collections.Generic.HashedSet is not longer included.

I used this collection type in many parts of my code, because it has a "AddAll" method, which it very useful for me.

However - now in the same namespace are only 3 types left: LinkedHashSet<T> ReadOnlySet<T> SychronizedSet<T>

None of them has such a method. I tried to implement it by myself, but it does not work.

Here is what I did:

  1. Created an interface "IMySet"

    public interface IMySet : ISet { void AddAll(IEnumerable items); }

  2. Copied full source from "LinkedHashSet" implementation, renamed it to "TestSet" and replaced the derived interface.

before:

public class TestSet<T> : ISet<T>

after:

public class TestSet<T> : IMySet<T>

Unfortunately this does not work. If I try to save an object, which implements IMySet, an error occurs:

NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)

I don't understand what's the problem. Can anyone please help?

The correct solution is to use the equivalent UnionWith() method from .Net's `ISet<T>' :

Modifies the current set so that it contains all elements that are present in either the current set or the specified collection.

Example:

ISet<int> set = new Hashset<int>();
set.UnionWith(newElements);

The point is, that NHibernate can/will use implementation of ISet<T> - which is available in NHibernate distribution (dll) . Most likely the PersistentGenericSet<T> .

Brand new interface IMySet<T> is simply not expected... not supported.

But this could be "easily" solved by some custom extension:

public static class MyExtensions
{
    public static bool AddAll<T>(this ISet<T> list, IEnumerable<T> items)
    {
        // some very simple implementation:
        bool success = true;
        foreach (var item in items)
        {
            success &= list.Add(item);
        }
        return success;
    }
}

And then we can use it as we used to:

// entity with ISet
public class MyEntity
{
    ...
    public virtual ISet<Employee> Employees { get; set; }
}

// some method adding more items
var myEntity = ...
myEntity.Employees.AddAll(collectionOfEmployees)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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