4

I have following method that registers a contact in database, but before register I check the contact exists or not:

bool RegisterContact(Contact contactInfo) { 
          bool entityExists =
                        _dbContext.Contacts.FirstOrDefault(
                            p => (p.FilesID.Equals(contactInfo.FilesID))
                                 && (p.EmailAddress ==
                                     (string.IsNullOrEmpty(
                                         contactInfo.EmailAddress)
                                         ? p.EmailAddress
                                         : contactInfo.EmailAddress))
                                 &&
                                 (p.DisplayName ==
                                  (string.IsNullOrEmpty(
                                      contactInfo.DisplayName)
                                      ? p.DisplayName
                                      : contactInfo.DisplayName)));
                                                                          }

this query includes the fields that contain value (not null) in search condition (FilesID, EmailAddress, DisplayName)

this technique works fine in MSSQL, today i changed the database manager to PostgreSQL and use Npgsql.

All things work except above linq query, which raises an exception with message of : "could not determine data type of parameter $2"

I was forced to solve it in this way:

bool RegisterContact(Contact contactInfo)
{ 
    Contact entityExists = null;

      if (string.IsNullOrEmpty(contactInfo.EmailAddress) &&
                        (string.IsNullOrEmpty(contactInfo.DisplayName)))
                        entityExists =
                            _dbContext.Contacts.FirstOrDefault(
                                p => p.FilesID.Equals(contactInfo.FilesID));

                    if (!string.IsNullOrEmpty(contactInfo.EmailAddress) && string.IsNullOrEmpty(contactInfo.DisplayName))
                        entityExists =
                            _dbContext.Contacts.FirstOrDefault(
                                p =>
                                    p.FilesID.Equals(contactInfo.FilesID) &&
                                    p.EmailAddress == contactInfo.EmailAddress);

                    if (string.IsNullOrEmpty(contactInfo.EmailAddress) && !string.IsNullOrEmpty(contactInfo.DisplayName))
                        entityExists =
                            _dbContext.Contacts.FirstOrDefault(
                                p =>
                                    p.FilesID.Equals(contactInfo.FilesID) &&
                                    p.DisplayName == contactInfo.DisplayName);


                    if (!string.IsNullOrEmpty(contactInfo.EmailAddress) &&
                        !string.IsNullOrEmpty(contactInfo.DisplayName))
                        entityExists =
                            _dbContext.Contacts.FirstOrDefault(
                                p =>
                                    p.FilesID.Equals(contactInfo.FilesID) &&
                                    p.EmailAddress == contactInfo.EmailAddress &&
                                    p.DisplayName == contactInfo.DisplayName);

}

Is this Npgsql bug or by design? any known solutions/workarounds for the problem?

Plebsori
  • 1,075
  • 9
  • 23
Mojtaba Tajik
  • 1,725
  • 16
  • 34
  • Possible duplicate of [Linq to SQL multiple conditional where clauses](http://stackoverflow.com/questions/10323066/linq-to-sql-multiple-conditional-where-clauses) – krillgar Feb 04 '16 at 13:46

1 Answers1

0

I currently have the same cases. I think the problem is the lack of recognition, by NpgSQL, of string.IsNullOrEmpty.

I replaced the test with a check on empty string, always recognizing as not NULL the input parameter.

-- bad

        var data = from art in _ctx.Set<Soleo.Model.DLAR>()
                   from iva in _ctx.Set<Soleo.Model.DLAI>().Where(k => k.DITTA == art.DITTA && k.COD == art.CIVA).DefaultIfEmpty()
                   from fam in _ctx.Set<Soleo.Model.DLFA>().Where(k => k.DITTA == art.DITTA && k.COD == art.FAM).DefaultIfEmpty()
                   from mar in _ctx.Set<Soleo.Model.DLMA>().Where(k => k.DITTA == art.DITTA && k.COD == art.MAR).DefaultIfEmpty()
                   from udm in _ctx.Set<Soleo.Model.DLUM>().Where(k => k.DITTA == art.DITTA && k.COD == art.UM).DefaultIfEmpty()
                   where art.DITTA == DLAUTH.Config.Current.DITTA && art.COD.Contains(sel_cod) && art.DES.Contains(sel_des)
                   && (string.IsNullOrEmpty(sel_fam) || string.Compare(art.FAM, sel_fam, true) == 0)
                   && (string.IsNullOrEmpty(sel_mar) || string.Compare(art.MAR, sel_mar, true) == 0)
                   && (art.DIS >= sel_dis_da && art.DIS <= sel_dis_a)
                   select new
                   {
                       COD = art.COD,
                       DES = art.DES,
                       DES_UDM = udm.DES,
                       DES_MAR = mar.DES,
                       DES_FAM = fam.DES,
                       DES_CIVA = iva.DES,
                       MAG1 = art.MAG1,
                       MAG2 = art.MAG2,
                       DES_DIS = art.DIS == 1 ? "Si" : "No"
                   };

-- good:

            var data = from art in _ctx.Set<Soleo.Model.DLAR>()
                   from iva in _ctx.Set<Soleo.Model.DLAI>().Where(k => k.DITTA == art.DITTA && k.COD == art.CIVA).DefaultIfEmpty()
                   from fam in _ctx.Set<Soleo.Model.DLFA>().Where(k => k.DITTA == art.DITTA && k.COD == art.FAM).DefaultIfEmpty()
                   from mar in _ctx.Set<Soleo.Model.DLMA>().Where(k => k.DITTA == art.DITTA && k.COD == art.MAR).DefaultIfEmpty()
                   from udm in _ctx.Set<Soleo.Model.DLUM>().Where(k => k.DITTA == art.DITTA && k.COD == art.UM).DefaultIfEmpty()
                   where art.DITTA == DLAUTH.Config.Current.DITTA && art.COD.Contains(sel_cod) && art.DES.Contains(sel_des)
                   && (string.Compare(sel_fam, "", true) == 0 || string.Compare(art.FAM, sel_fam, true) == 0)
                   && (string.Compare(sel_mar, "", true) == 0 || string.Compare(art.MAR, sel_mar, true) == 0)
                   && (art.DIS >= sel_dis_da && art.DIS <= sel_dis_a)
                   select new
                   {
                       COD = art.COD,
                       DES = art.DES,
                       DES_UDM = udm.DES,
                       DES_MAR = mar.DES,
                       DES_FAM = fam.DES,
                       DES_CIVA = iva.DES,
                       MAG1 = art.MAG1,
                       MAG2 = art.MAG2,
                       DES_DIS = art.DIS == 1 ? "Si" : "No"
                   };

But I do not think this is the solution. I will report the case to NpgSQL.