LINQ query fails for NULL values - linq

var query = from t1 in Table1
join t2 in Table2
on new { t1.Id }
equals new { t2.Id}
select new
{
t1.Id,
t1.FirstName,
t1.MiddleName,//allows null values in the database
t1.LastName,
t1.phone //allows null values in the database
};
if(query.Count()>0)//fails here"The value for column MiddleName in table'Table1' is DBNULL"
{
}
Is there a way in which I can get all the rows including null values for middleName and Phone in my LINQ query?

If you are using linq-to-datasets you must manually convert nullable columns to null because their value in DataRow is DBNull.Value. In strongly typed DataSet you should be able to do something like:
var query = from t1 in Table1
join t2 in Table2
on new { t1.Id }
equals new { t2.Id}
select new
{
t1.Id,
t1.FirstName,
t1.IsMiddleNameNull ? null : t1.MiddleName,
t1.LastName,
t1.IsPhoneNull ? null : t1.Phone
};
In untyped DataSet you will call something like t1.IsNull("MiddleName") ? null : t1["MiddleName"]

It sounds like the metadata is out of sync with your DB schema. It seems as if when the classes were generated for your schema MiddleName was not nullable, but now it is. If that's the case, you need to refresh your EDMX if you're using Entity Framework or refresh your classes if you're using LINQ to SQL.

Could you please give this a shot
var query = from t1 in Table1
join t2 in Table2
on new { t1.Id }
equals new { t2.Id}
select new
{
Id = t1.Id,
FirstName = t1.FirstName,
MiddleName = t1.MiddleName,//allows null values in the database
LastName = t1.LastName,
Phone = t1.phone //allows null values in the database
};
if(query.Count()>0)//fails here"The value for column MiddleName in table'Table1' is DBNULL"
{
}

The problem is that a new anonymous object has its properties defined on-the-fly with types inferred from the values.
In such a line
MiddleName = t1.MiddleName,//allows null values in the database
a new property called MiddleName is created whose type is t1.MiddleName's type. But if t1.MiddleName is null, what is the type ??? Null has no type.
To prevent any ambiguousity simply put
MiddleName = (string)t1.MiddleName,
to let the compiler know that anyway it's a string, even if not provided.

Related

How to check record is fully empty on left join in jooq query

I try to fetch a record from table with left join on another table. An information in the second table can be not found but I expect an information from the first table.
val citizenship = Tables.COUNTRIES.`as`("citizenship")
try {
return context.selectFrom(Tables.CLIENT_PROJECTIONS
.leftJoin(citizenship).on(
Tables.CLIENT_PROJECTIONS.CITIZENSHIP_COUNTRY_CODE.eq(
citizenship.CODE_ALPHA2
)
)
).where(Tables.CLIENT_PROJECTIONS.ID.eq(id)).fetchOne {
val clientProjection = ClientProjectionMapper.map(it.into(Tables.CLIENT_PROJECTIONS)) ?: return#fetchOne null
clientProjection.citizenship = CountryMapper.map(it.into(citizenship))
clientProjection
}
} catch (ex: DataAccessException) {
logger.error("Failed to access to database", ex)
throw ex
}
I convert data from CountriesRecord to Entity in CountryMapper:
object CountryMapper : RecordMapper<CountriesRecord, Country> {
override fun map(record: CountriesRecord?): Country? = when {
record != null -> {
Country(
countryCode = record.codeAlpha,
title = record.title
)
}
else -> {
null
}
}
}
But if query returns null in every fields of CountriesRecord my map method receive a non-nullable entity but everyone fields of this entity is empty.
I can check every field of CountriesRecord is it null but i think that isn't good idea. Can I check it by another more best way? May be I should write more correct query to database?
A LEFT JOIN in SQL does exactly that. It produces nulls for all columns of the left joined table for which there was no match in the join's ON clause.
You don't have to check whether each column is null. The primary key will be good enough, because that should have a NOT NULL constraint on it, meaning that if the primary key value is null (record.codeAlpha), then that must be because of the LEFT JOIN.
Change your second mapper to this:
object CountryMapper : RecordMapper<CountriesRecord, Country> {
override fun map(record: CountriesRecord?): Country? = when {
record?.codeAlpha != null -> {
Country(
countryCode = record.codeAlpha,
title = record.title
)
}
else -> {
null
}
}
}

Using distinct in Spring data over multiple columns

My domain model is like this:
CollectedData {
String name;
String description;
int count;
int xAxis,
int yAxis
}
Using Spring data repository query, I would like to retrieve all the unique rows (unique with name, xAxis, yAxis)
I am trying something like this
#Query("select distinct a.name, a.xAxis, a.yAxis from CollectedData a")
List<CollectedData> findAllDistinctData();
So, when I do
List<CollectedData> records= findAllDistinctData();
for (CollectedData record : records) { //Exception on this line
}
Exception
[Ljava.lang.Object; cannot be cast to CollectedData.
Is there any other way to write query for this ?
#Query return ArrayList of Object(s) instead of specific type of object. so you have to define some thing like
#Query("select distinct a.name, a.xAxis, a.yAxis from CollectedData a")
List<Object> findAllDistinctData();
then cast according to your requirement,
List<Object> cdataList=findAllDistinctData();
for (Object cdata:cdataList) {
Object[] obj= (Object[]) cdata;
String name = (String)obj[0];
String description = (String)obj[1];;
...
}
Instead of returning an object you can use JPA's constructor expression feature to return a more specific object holding only the columns you're interested in. See also following answer:
JPQL Constructor Expression - org.hibernate.hql.ast.QuerySyntaxException:Table is not mapped
According to your example you could create a new Object with only the columns you are interested in:
SELECT DISTINCT new com.mypackage.MyInterestingCollectedData(a.name, a.xAxis, a.yAxis) from CollectedData a
If you want to select complete object based on distinct values of multiple columns,
In that case the native query would be the option.
e.g.
#Query(
value = "select distinct on (column1, column2, column3) * From my_table where someId=: order by column1 asc,column2 desc,column3 desc,column4 desc",
nativeQuery = true
)
fun finalAllDistinctBy(containerId: String): List<MyTable>

showing multiple rows from database in datagridview using entity framework

I am trying to show multiple records from database in datagridview but I'm having only a single record all the time.
2 tables are involved in this query, from 1st table I acquire all the id's those fulfill the condition and from 2nd table I am getting the user information.
1st table is tblUsers_Roles and 2nd is tblUsers.
These tables have primary/foriegn key relationship.
Here is my code:
IEnumerable<tblUsers_Role> id = db.tblUsers_Role.Where(a => a.User_Role == selectRole);
foreach (var user in id)
{
var userinfo = from b in db.tblUsers
where b.User_Id == user.User_Id
select new { b.First_Name, b.Last_Name, b.Status, b.Authenticated };
dgvResults.DataSource = userinfo.ToList();
dgvResults.Show();
}
You are assigning the grid in the loop. That is not going to work. Maybe something like this will work:
var userinfo =(from ur in db.tblUsers_Role
join u in db.tblUsers
on ur.User_Id equals u.User_Id
where ur.User_Role == selectRole
select new
{
u.First_Name,
u.Last_Name,
u.Status,
u.Authenticated
}).ToList();
dgvResults.DataSource = userinfo;
dgvResults.Show();
Or a alteretive would be like this:
var roles=db.tblUsers_Role
.Where(a => a.User_Role == selectRole)
.Select (a =>a.User_Id).ToList();
var userinfo=
(
from u in db.tblUsers
where roles.Contains(u.User_Id)
select new
{
u.First_Name,
u.Last_Name,
u.Status,
u.Authenticated
}
).ToList();
dgvResults.DataSource = userinfo;
dgvResults.Show();
Not as nice as the first one. But maybe you understand the concept.

How to declare the result of query in LINQ to Entities

I just started using MS entity framework and have the following problem with LINQ. I will simplify my problem to make it clearer; let's say that I have three tables in SQL Server database:
CustomerData (PK is CustomerId, the table also has some twenty columns to hold customer data).
CustomerData1 (holds some data for the customer in one to one relationship).
CustomerData2 (also holds some data for the customer in one to one relationship).
I know the data with one to one relationship should better be in the same table, but this is some corporate db and it is not possible to alter the original table (so all our data should be in the separate tables).
Now I want to display a list of customer with their data from CustomerData table and add some data columns from CustomerData1 via join.
On the other hand, I want to display a list of customers and add some data from the other table CustomerData2 via join.
So the data is basically the same both times except that in the first case the result includes some columns from CustomerData1 and in the second case some data from CustomerData2 table.
So I created the class Customer with properties for all relevant columns in CustomerData table and added properties for columns that should be included from CustomerData1 and properties that should be included from CustomerData2.
All columns should be included each time, except that when first call will be made the properties that map to CustomerData2 table will be empty and during the second call the properties that map to CustomerData1 table will be empty.
For this I wanted to create one function so I tried to create it like this:
Input parameter in function is whether data from CustomerData1 or CustomerData2 is included.
if (firstList)
{
var query1 = from obj in CustomerData
join rel in CustomerData1
on obj.CustomerId equals rel.CustomerId
select new { obj, rel };
}
if (secondList)
{
var query2 = from obj in CustomerData
join rel in CustomerData2
on obj.CustomerId equals rel.CustomerId
select new { obj, rel };
}
So this code gives me the anonymous type based on the input parameter. Now I want to create Customer objects and order it (order is always the same, it does not depend on input parameter). So I want to create a list of ordered customers and include additional data based on the input parameter.
var query3 = <previous_query_variable>.Select(f => new Customer {
Id = f.obj.CustomerId,
Name = f.obj.CustomerName,
... other columns from Customer table (a lot of them)
//and then add some additional columns based on the input parameter
Data1 = f.rel.someDataFromCustomer1, //only when firstList == true, otherwise empty
Data2 = f.rel.someDataFromCustomer2 //only when secondList == true, otherwise empty
}).OrderBy(f => f.Name); //order by customer name
Of course this does not compile, since both vars are inside if statements. I know I could copy this last statement (var query3 = ...) inside both if statements and include only relevant assignments (Data1 or Data2), but I don't want to assign properties that map to CustomerData table twice (once in both if statements) nor I want to order twice.
How can I solve this problem? I am using .NET 4.
You cannot declare a variable for an anonymous type up-front, i.e. before your two if statements. (Something like var query = null is not supported.) You will have to create a helper type and project into it, like so:
public class ProjectedCustomerData
{
public CustomerData CustomerData { get; set; }
public CustomerData1 CustomerData1 { get; set; }
public CustomerData2 CustomerData2 { get; set; }
}
And then the projection:
IQueryable<ProjectedCustomerData> resultQuery = null;
if (firstList)
{
resultQuery = from obj in CustomerData
join rel in CustomerData1
on obj.CustomerId equals rel.CustomerId
select new ProjectedCustomerData
{
CustomerData = obj,
CustomerData1 = rel
};
}
if (secondList)
{
resultQuery = from obj in CustomerData
join rel in CustomerData2
on obj.CustomerId equals rel.CustomerId
select new ProjectedCustomerData
{
CustomerData = obj,
CustomerData2 = rel
};
}
var query3 = resultQuery.Select(f => new Customer {
Id = f.CustomerData.CustomerId,
Name = f.CustomerData.CustomerName,
// ...
Data1 = f.CustomerData1.someDataFromCustomer1,
Data2 = f.CustomerData2.someDataFromCustomer2
}).OrderBy(f => f.Name);
I am not sure if Customer is an entity in your model or only a class you are using for your projection. If it's an entity you have to change the last code because you cannot project into an entity (basically you would need another helper type for your projection).

Linq distinct problem

I am new to using LINQ, right now i have a query in sql with multiple inner joins and it works fine. I am trying to change this to a equivalent LINQ code, i could able to implement LINQ except for the Distinct fact i am using in my query...
my query
select DT.[Name], count(distinct([FeatureControlID])) as [Value], DT.[Weight]
from [DocumentTypes] DT inner join
[DocumentTypesSchema] DTS on
DT.[ID] = DTS.[DocumentTypeID] inner join
ProductsFeaturesControlsDocumentValues [PFCDV] on
DTS.[ID] = PFCDV.[SchemaID]
where [PFCDV].[ProductID] = 72
group by DT.[Name], DT.[Weight], [DT].[ID]
order by [DT].[ID]
and my LINQ without the Distinct condition is as below
from dt in db.DocumentTypes
join dts in db.DocumentTypesSchemas on new { ID = dt.ID } equals new { ID = dts.DocumentTypeID }
join pfcdv in db.ProductsFeaturesControlsDocumentValues on new { ID = dts.ID } equals new { ID = pfcdv.SchemaID }
where
pfcdv.ProductID == 72
group new {dt, pfcdv} by new {
dt.Name,
dt.Weight,
dt.ID
} into g
orderby
g.Key.ID
select new {
g.Key.Name,
Value = (Int64?)g.Count(p => p.pfcdv.FeatureControlID != null),
Weight = (System.Decimal?)g.Key.Weight
}
can anyone give me a hand on this? actually the linq code executes without the Distinct feature i used in the code.
Have you tried something like this?
...
select new {
g.Key.Name,
Value = (Int64?)g.Select(p => p.pfcdv.FeatureControlID)
.Where(id => id != null)
.Distinct().Count()
Weight = (System.Decimal?)g.Key.Weight
}

Resources