Use Dynamic LINQ Library with join - c#

Following is the UI :
And this is code snippet i am using to fire dynamic where clause :
public void bind()
{
string filter = "";
if (!string.IsNullOrEmpty(txtPart.Text))
{
filter = filter + "masterinv.inv_item_id = " + txtPart.Text;
}
if (!string.IsNullOrEmpty(txtDescription.Text))
{
if (!string.IsNullOrEmpty(filter))
{
filter = filter + " || masterinv.description = " + txtDescription.Text;
}
else
{
filter = filter + "masterinv.description = " + txtDescription.Text;
}
}
if (!string.IsNullOrEmpty(txtVendor.Text))
{
if (!string.IsNullOrEmpty(filter))
{
filter = filter + " || vendor.vendor_name = " + txtVendor.Text;
}
else
{
filter = filter + "vendor.vendor_name = " + txtVendor.Text;
}
}
InventoryDataContext dc = new InventoryDataContext(InventoryDBContext.GetConnectionstring());
var searchResult = (from masterinv in dc.OMS_REF_Master_Inventories
join vendor in dc.OMS_REF_Vendors on masterinv.inv_item_id equals vendor.inv_item_id
Where(filter)
select new OMS_REF_Master_Inventory
{
inv_item_id = masterinv.inv_item_id,
description = masterinv.description,
unit_of_measure = masterinv.unit_of_measure,
lot_id = masterinv.lot_id,
serial_id = masterinv.serial_id,
mfg_id = masterinv.mfg_id,
mfg_item_id = masterinv.mfg_item_id,
item_status_current = masterinv.item_status_current,
cm_unit_cost = masterinv.cm_unit_cost,
sync_dte = masterinv.sync_dte
}).ToList();
searchResult;
}
In the above code filter created on the basis of combination of combo box and text field
selection.
Out of these one filter is :
masterinv.inv_item_id = 'A' || masterinv.description = 'F' || vendor.vendor_name = 'V'
it may vary depend upon the combobox value selection. All cases of Combo box present in BuildQueryFilter Method.
PROBLEM :
I am not able to fire where clause in this join. Where i am going wrong ?

I think you cannot use those % with linq queries.
Instead of % you can use Contains()/StartsWith()/EndsWith()
refer this for more info...
How to do SQL Like % in Linq?
How to do a LIKE query with linq?
Or
Use Sql Methods..
where SqlMethods.Like(c.CustomerName, "%/abc/%")

Related

SQL combine rows to be able to filter

I want to combine some rows, so I can filter the customers properly.
SELECT
StammIndex
, sPropSet
, bProp01
FROM [Properties] as properties
RIGHT JOIN [Kunden] as kunden
ON Kunden.StammIndex = properties.KundenIndex
"StammIndex" is the customers ID,
"sPropSet" is the property and
"bProp01" tells you if the property is checked (1) or not checked (0)
The problem is, that customers that have checked the property at least once are saved in the Database.
That means, that the customer IDs will be saved multiple times.
Now I want to get all customers, that didn't check the "Serienbrief" property.
SELECT
StammIndex
, sPropSet
, bProp01
FROM [Properties] as properties
RIGHT JOIN [Kunden] as kunden
ON Kunden.StammIndex = properties.KundenIndex
WHERE NOT (sPropSet = 'Serienbrief' AND bProp01 = 1) OR sPropSet IS NULL
Here you can see that customer '10001' is still there, because he got two properties. I want customer '10001' removed too, because he also got the property "Serienbrief" checked.
First post on stackoverflow, so sorry if I didn't explain my problem properly.
If you got any further questions, please feel free to ask.
EDIT*
My Filter is in C#. The Code behind looks like this
internal class FilterEigenschaften
{
public static List<UndBlock> FilterEigenschaftenListe = new List<UndBlock>();
public List<AdressenListe> Filter(Connection conn)
{
Criteria undBlockCriteria = conn.CreateCriteria();
foreach (UndBlock undBlock in FilterEigenschaften.FilterEigenschaftenListe)
{
Criteria oderBlockCriteria = conn.CreateCriteria();
foreach (OderBlock oderBlock in undBlock.OderBlock)
{
Criteria filterBlockCriteria = conn.CreateCriteria();
foreach (FilterBlock filterBlock in oderBlock.FilterBlock.Where(y => !string.IsNullOrEmpty(y.Wert)))
{
filterBlockCriteria.AddAnd("sPropSet", Operator.Equal, filterBlock.Kriterium);
filterBlockCriteria.AddAnd("bProp" + this.FiterSqlEigenschaftenFelder(conn, filterBlock), Operator.Equal, 1);
if (filterBlock.Operand == "Ist markiert")
{
}
else
{
}
}
oderBlockCriteria.AddOr(filterBlockCriteria);
}
undBlockCriteria.AddAnd(oderBlockCriteria);
}
string cmdText = $"SELECT Distinct(Kunde.StammIndex) " +
$"FROM {conn.Tablenames[4]} AS Kunde " +
$"RIGHT JOIN {conn.Tablenames[12]} AS Properties " +
$"ON Kunde.StammIndex = Properties.KundenIndex " +
$"WHERE {undBlockCriteria}";
return WordSqlAdressen.GetAdressenListe(conn, cmdText);
}
private string FiterSqlEigenschaftenFelder(Connection conn, FilterBlock filterBlock)
{
for (int i = 1; i < 31; i++)
{
using (Command cmd = conn.CreateCommand($"SELECT sProp{i:00} " +
$"FROM {conn.Tablenames[13]} " +
$"WHERE sPropSet = '{filterBlock.Kriterium}'"))
{
using (DataReader dr = cmd.ExecuteReaderEx())
{
while (dr.Read())
{
if (dr.GetString((0)) == filterBlock.Wert)
{
return i.ToString("00");
}
}
}
}
}
return null;
}
}
I can only use one SQL statement to see, if the property is checked or not checked
You just need to move your condition to your join rather than the where clause.
I.e.
SELECT
*
FROM Kuden k
LEFT JOIN Properties p
ON k.StammIndex = p.KudenIndex
AND p.sPropSet = 'Serienbrief'
AND p.bProp01 = 1
WHERE p.KudenIndex IS NULL;

Display two or more displaymembers in binded listbox

After joining two tables, i want to display the name and the first_name of user:
string name_p = list_profiles.Text;
int id_profile;
var profile = SundicappEntities.Instance.users_profiles.First(u => u.name_p== name_p);
id_profile = profile.id_profile;
var q =
from user in SundicappEntities.Instance.users
join map in SundicappEntities.Instance.user_profile_map on user.id_user equals map.id_user
where map.id_profile==id_profile
select new
{
user.name_user,
user.f_name_user
};
usersBindingSource1.DataSource = q.ToList();
listBox_map.DataSource = usersBindingSource1;
listBox_map.DisplayMember = "name_user"+" " + "f_name_user";
It returns the correct data, but it display it like this:
{name_user=xxxx.f_name_user=yyyy}
My problem is how to display many displaymembers in listbox!
Thank you to help me.
Create a custom property in your class object that returns you the correct string.
public string ListBoxItemDisplayText
{
get
{
return name_user + " " + f_name_user ;
}
}
You can create this property in the linq new construct as well
select new
{
ListBoxItemDisplayText = user.name_user + " " + user.f_name_user
};
Bind this property to the DisplayMember property.
listBox_map.DisplayMember = "ListBoxItemDisplayText";

C# LINQ Dynamic Select with all type of data

I am implementing search by using dynamic LINQ, where the query gets column name and search value in runtime. In this way, I need to parse the data according to the column type-
if (isNumeric)
{
int x = Int32.Parse(txtHistorySearch.Text);
truncatedData = ((IQueryable<object>)rawData).Where(columnName + "=#0", x).ToList();
}
else if (DateTime.TryParse(txtHistorySearch.Text, out temp))
{
var parsedDt = DateTime.Parse(txtHistorySearch.Text);
var nextDay = parsedDt.AddDays(1);
truncatedData = ((IQueryable<object>)rawData).Where(columnName + ">= #0 && " + columnName + " < #1", parsedDt, nextDay).ToList();
}
else
{
truncatedData = ((IQueryable<object>)rawData).Where(columnName + "=#0", searchValue).ToList();
}
Can this be done for all data types using single where clause?
You can do this using expression trees.
https://msdn.microsoft.com/en-us/library/bb397951.aspx
https://msdn.microsoft.com/en-us/library/bb882637.aspx

merge many collection lists into a single collection list in entity framework

I have Lots of collection list in my page what i want to do just
merge all collection list into single collection list in entity
framework.I already Defined class or model but when i retrieve it
doesn't return any thing.
using (FinanceEntities fentities = new FinanceEntities(value.credentials))
{
try
{
int str=DateTime.DaysInMonth(Valcol.year,Valcol.month);
string FD = Valcol.year + "-" + Valcol.month + "-" + "01";
string LD = Valcol.year + "-" + Valcol.month + "-" + str;
DateTime FirstDate = DateTime.Parse(FD);
DateTime vdate = DateTime.Parse(LD);
List<PayNoModel> PayNoModel = GetPayNoModel(value);
List<VoucherNoModel> VoucherNoModel=GetVoucherNoModel(value);
List<PayNoModel> PayNoModel2 = GetPayNoModel2(value);
List<PayNoModel> PayNoModel3 = GetPayNoModel3(value);
List<VoucherNoModel> VoucherNoModel2 = GetVoucherNoModel2(value);
List<ChequeNoModel> ChequeNoModel = GetChequeNoModel(value);
List<VoucherNoDiffModel> VoucherNoDiffModel = GetVoucherNoDiffModel(value);
List<VoucherNoNarationModel> VoucherNoNarationModel = GetVoucherNoNarationModel(value);
query = (from p in PayNoModel
from v in VoucherNoModel
from p2 in PayNoModel2
from p3 in PayNoModel3
from v2 in VoucherNoModel
from ch in ChequeNoModel
from voucdiff in VoucherNoDiffModel
from voucnarr in VoucherNoNarationModel
select new ReconcileReportModel
{
}).ToList<ReconcileReportModel>();
}
catch (Exception ex)
{
var s = ex.Message;
}
}
return query;
}

How can I secure SQL parameters with entity framework SqlQuery?

I have this method that should take an unknown amount of id's.
I got this method almost done but it isnt secure yet for obvious reasons, i know i could write my own method to strip the parameters but i would be more comfortable by using some build in method for this.
Here is the method
public static List<LocationModel> FetchCitiesByAreas(IEnumerable<string> areas)
{
using (var db = new BoligEnt())
{
var sqlQuery = new StringBuilder();
var first = true;
sqlQuery.Append("SELECT DISTINCT a.city AS City, a.zip AS Zip ");
sqlQuery.Append("FROM zip_city AS a ");
sqlQuery.Append("WHERE country = 1 ");
foreach (var d in areas)
{
if (first)
{
sqlQuery.Append("AND a.area_id = '" + d + "'");
first = false;
}
else
{
sqlQuery.Append("OR a.area_id = '" + d + "'");
}
}
return db.Database.SqlQuery<LocationModel>(sqlQuery.ToString()).ToList();
}
}
i know it have this function built in but as i stated earlier i dont know the exact amount of ids that will come in
db.Database.SqlQuery<LocationModel>("SELECT * FROM table WHERE id = #p0 ;", id).ToList();
Thanks
While I completely agree with paqogomez, in that you should just use LINQ to do the query, the .SqlQuery has the ability to take a parameter array. You could change your statement to look like this:
var sqlQuery = new StringBuilder();
sqlQuery.Append("SELECT DISTINCT a.city AS City, a.zip AS Zip ");
sqlQuery.Append("FROM zip_city AS a ");
sqlQuery.Append("WHERE country = 1 ");
for (int i = 0; i < areas.Count; i++)
{
if (i == 0)
{
sqlQuery.Append("AND (a.area_id = #p" + i.ToString());
}
else
{
sqlQuery.Append(" OR a.area_id = #p" + i.ToString());
}
}
sqlQuery.Append(")");
var results = db.Database.SqlQuery<LocationModel>(sqlQuery.ToString(), areas.ToArray()).ToList();
I added the missing parenthesis needed to your query to correctly filter out the OR results as well. I've also taken the assumption that areas is something like a List, or at least something you can easily get the count from.
Why dont you just use Linq?
var locations = (from zip in db.zip_city
where areas.Contains(zip.area_id) && zip.Country == 1
select new LocationModel{
City = zip.City,
Zip = zip.Zip
})
.Distinct()
.ToList();
If you still want to parameterize your query, you need to use EntityCommand
Also note that your query will fail because you havent put parenthesis around your OR statements.
I suggest structuring your sql like this:
string sqlQuery =
#"SELECT DISTINCT a.city AS City, a.zip AS Zip
FROM zip_city AS a
WHERE country = 1 AND (1=0 "
for (int i = 0; i < areas.Count; i++)
{
sqlQuery.Append("OR a.area_id = #d" + i.ToString() + " ");
}
sqlQuery.Append(")");

Categories

Resources