Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here is my solution</p> <p>Entities: </p> <pre><code>public class TaskTest : Entity&lt;TaskTest&gt; { public virtual string Name { get; set; } public virtual IList&lt;TagTest&gt; Tags { get; set; } public TaskTest() { Tags = new List&lt;TagTest&gt;(); } } public class TagTest : Entity&lt;TagTest&gt; { public virtual string Name { get; set; } } </code></pre> <p>Do not take in the consideration Entity&lt;>. Is is generic as we've implemented a IEquatable interface</p> <p>Next Mappings: </p> <pre><code>public class TaskTestMap : EntityMap&lt;TaskTest&gt; { public TaskTestMap() { Map(x =&gt; x.Name).Not.Nullable().Length(512); HasManyToMany(x =&gt; x.Tags).Table("TaskTag").Cascade.All(); } } public class TagTastMap : EntityMap&lt;TagTest&gt; { public TagTastMap() { Map(x =&gt; x.Name).Not.Nullable(); } } </code></pre> <p>I set cascade just to save tasgs on saving tasks.</p> <p>The repository with my criteria:</p> <pre><code>public IList&lt;TaskTest&gt; GetTaskByTagIds(IList&lt;long&gt; tagIds) { DetachedCriteria exists = DetachedCriteria.For&lt;TaskTest&gt;("t") .CreateAlias("t.Tags", "tags") .Add(Restrictions.EqProperty("t.Id", "task.Id")) .Add(Restrictions.In("tags.Id", tagIds.ToArray())) .SetProjection(Projections.GroupProperty("t.Id")) .Add(Restrictions.Eq(Projections.Count("t.Id"), tagIds.Count)); ICriteria criteria = GetSession().CreateCriteria&lt;TaskTest&gt;("task") .Add(Subqueries.Exists(exists)); return criteria.List&lt;TaskTest&gt;(); } </code></pre> <p>And the unit test which pass on my side:</p> <pre><code> [Test] public void TestTaskTest() { //Insert data; var task1 = new TaskTest {Name = "task1"}; var task2 = new TaskTest {Name = "task2"}; var task3 = new TaskTest {Name = "task3"}; var tag1 = new TagTest {Name = "tag1"}; var tag2 = new TagTest {Name = "tag1"}; var tag3 = new TagTest {Name = "tag1"}; task1.Tags.Add(tag1); task1.Tags.Add(tag2); task2.Tags.Add(tag1); task2.Tags.Add(tag3); task3.Tags.Add(tag3); _repository.AddToSession(task1); _repository.AddToSession(task2); _repository.AddToSession(task3); FlushAndClearSession(); //We will try to get all task which a taged with tag1 and tag2. The result should be task1 var tagsId = new List&lt;long&gt; {tag1.Id, tag2.Id}; var result = _repository.GetTaskByTagIds(tagsId); Assert.That(result, Is.Not.Null); Assert.That(result, Is.Not.Empty); Assert.That(result.Count, Is.EqualTo(1)); Assert.That(result[0].Name, Is.EqualTo("task1")); } </code></pre> <p>and the sql statement is:</p> <pre><code> exec sp_executesql N'SELECT this_.Id as Id50_0_, this_.Version as Version50_0_, this_.Name as Name50_0_ FROM [TaskTests] this_ WHERE exists ( SELECT this_0_.Id as y0_ FROM [TaskTests] this_0_ inner join TaskTag tags3_ on this_0_.Id=tags3_.TaskTestId inner join [TagTests] tags1_ on tags3_.TagTestId=tags1_.Id WHERE this_0_.Id = this_.Id and tags1_.Id in (@p0, @p1) GROUP BY this_0_.Id HAVING count(this_0_.Id) = @p2)', N'@p0 bigint,@p1 bigint,@p2 int', @p0=9000,@p1=9001,@p2=2 </code></pre> <p>Regards, /Ion</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload