Linq, doing Join comparing to Like

Asked

Viewed 756 times

2

I have a question regarding Linq. As I have observed some codes, they usually use as an example:

 var _s = (from p in exemplo1
           join q in exemplo2 on p.blabla equals q.blablabla

I would like to know if a structure like for example that I will show below is valid and how I can create it:

var _s = (from p in exemplo1
          join q in exemplo2 on SqlMethods.Like(p.blabla, "%" + q.blablabla + "%")
  • I tried, but he "forces" start with on and then equals in the structure, but I think I killed the riddle... I’ll post the answer...

  • This will generate error ... LINQ to Entities does not recognize the method 'Boolean Like(System.String, System.String)' method, and this method cannot be translated into a store expression.

  • @Marconciliosouza After a while thinking I tested a solution and it worked in a similar way to my doubt. I posted in the answer.

3 answers

1

You can use the method Contains to do this.

using (var DBCtx = new RohrdbContext())
{

    var s = (from p in DBCtx.exemplo1
            from q in DBCtx.exemplo2
            where q.blablablabla.Contains(p.blabla)
            select p);

    // eu particulamente prefiro dessa forma.

    var s2 = DBCtx.exemplo1
        .Select(p => new
        {
            P = p,
            C = DBCtx.exemplo2.FirstOrDefault(C => C.Id = p.Id),

        })
        .Where(p => p.P.blablablabla.Contains(p.C.blabla)); 
        //.Where(p => p.P.blablablabla.StartsWith(p.C.blabla)); // Inicio da string
        //.Where(p => p.P.blablablabla.EndsWith(p.C.blabla)); // fim da string
}

1

Like Extension Linq / SQL

Likeextension class

Tested in . NET 5

 public static class LikeExtension {

    private static string ColumnDataBase<TEntity, TKey>(IModel model, Expression<Func<TEntity, TKey>> predicate) where TEntity : class {

        ITable table = model
            .GetRelationalModel()
            .Tables
            .First(f => f
                .EntityTypeMappings
                .First()
                .EntityType == model
                .FindEntityType(predicate
                    .Parameters
                    .First()
                .Type
            ));

        string column = (predicate.Body as MemberExpression).Member.Name;
        string columnDataBase = table.Columns.First(f => f.PropertyMappings.Count(f2 => f2.Property.Name == column) > 0).Name;

        return columnDataBase;

    }

    public static IQueryable<TEntity> Like<TEntity, TKey>(this DbContext context, Expression<Func<TEntity, TKey>> predicate, string text) where TEntity : class {

        string columnDataBase = ColumnDataBase(context.Model, predicate);
        return context.Set<TEntity>().FromSqlRaw(context.Set<TEntity>().ToQueryString() + " WHERE [" + columnDataBase + "] LIKE {0}", text);

    }

    public static async Task<IEnumerable<TEntity>> LikeAsync<TEntity, TKey>(this DbContext context, Expression<Func<TEntity, TKey>> predicate, string text, CancellationToken cancellationToken) where TEntity : class {

        string columnDataBase = ColumnDataBase(context.Model, predicate);
        return await context.Set<TEntity>().FromSqlRaw(context.Set<TEntity>().ToQueryString() + " WHERE [" + columnDataBase + "] LIKE {0}", text).ToListAsync(cancellationToken);

    }

    public static async Task<IEnumerable<TEntity>> LikeAsync<TEntity, TKey>(this IQueryable<TEntity> query, Expression<Func<TEntity, TKey>> predicate, string text, CancellationToken cancellationToken) where TEntity : class {

        DbSet<TEntity> entities = query as DbSet<TEntity>;
        string columnDataBase = ColumnDataBase(entities.EntityType.Model, predicate);
        return await entities.FromSqlRaw(query.ToQueryString() + " WHERE [" + columnDataBase + "] LIKE {0}", text).ToListAsync(cancellationToken);

    }

    public static IQueryable<TEntity> Like<TEntity, TKey>(this IQueryable<TEntity> query, Expression<Func<TEntity, TKey>> predicate, string text) where TEntity : class {

        DbSet<TEntity> entities = query as DbSet<TEntity>;
        string columnDataBase = ColumnDataBase(entities.EntityType.Model, predicate);
        return entities.FromSqlRaw(query.ToQueryString() + " WHERE [" + columnDataBase + "] LIKE {0}", text);

    }

}

Repository

    public async Task<IEnumerable<TEntity>> LikeAsync<TKey>(Expression<Func<TEntity, TKey>> predicate, string text, CancellationToken cancellationToken) {

        return await context.LikeAsync(predicate, text, cancellationToken);

    }

    public IQueryable<TEntity> Like<TKey>(Expression<Func<TEntity, TKey>> predicate, string text) {

        return context.Like(predicate, text);

    }

Use

 IQueryable<CountryEntity> result = countryRepository
     .Like(k => k.Name, "%Bra[sz]il%") /*Use Sync*/
     .Where(w => w.DateRegister < DateTime.Now) /*Example*/
     .Take(10); /*Example*/

Or

 IEnumerable<CountryEntity> result = await countryRepository
     .LikeAsync(k => k.Name, "%Bra[sz]il%", cancellationToken); /*Use Async*/

Or

 IQueryable<CountryEntity> result = context.Countries
     .Like(k => k.Name, "%Bra[sz]il%")
     .Where(w => w.Name != null); /*Example*/

Or

 List<CountryEntity> result2 = await context.Countries
     .Like(k => k.Name, "%Bra[sz]il%")
     .Where(w => w.Name != null) /*Example*/
     .ToListAsync(); /*Use Async*/

Or

 IEnumerable<CountryEntity> result3 = await context.Countries
     .Where(w => w.Name != null)
     .LikeAsync(k => k.Name, "%Bra[sz]il%", cancellationToken); /*Use Async*/

1


After a few minutes of kicking, I used this solution and it worked.

var _s = (from p in exemplo1
          from q in exemplo2
          where 
          SqlMethods.Like(p.blabla, "%" + q.blablabla + "%")

Browser other questions tagged

You are not signed in. Login or sign up in order to post.