I want to use dapper to query over dbf files. In my file example.dbf I have two columns:
Value - type NUMERIC
Name - type CHARACTER
I write class ExampleDbf
class ExampleDbf
{
public int Value { get; set; }
public string Name { get; set; }
}
Now I want to write two simple query
var listOne = connection.Query<ExampleDbf>("SELECT value FROM Example");
var listTwo = connection.Query<ExampleDbf>("SELECT name, value FROM Example");
ListOne are OK but when I execute listTwo I Have following System.Data.DataException:
Additional information: Error parsing column 0 (name=System.Byte[] - Object)
When I use standard DataReader I must write something like that
example.name = System.Text.Encoding.ASCII.GetString((byte[])reader["name"]).Trim();
Of course I may write something like this:
class ExampleDbf2
{
public int Value { get; set; }
public byte[] Name { get; set; }
public string StringName
{
get
{
return System.Text.Encoding.ASCII.GetString((byte[])Name ).Trim();
}
}
}
So now it works
var listTwo = connection.Query<ExampleDbf2>("SELECT name, value FROM Example");
But this solution is very ugly, maybe someone have better solution.
You could always return a dynamic, then map it to your object and perform the transformation operation during object initialization.
var listTwo = connection.Query<dynamic>("SELECT name, value FROM Example")
.Select(x => new ExampleDbf
{
Value = x.value,
Name = System.Text.Encoding.ASCII.GetString((byte[])x.name).Trim()
}).ToList();
Related
private IQueryable<SubjectDataViewModel> GetData()
{
var subject = this.DbContext.Subjects.AsQueryable(); //sql view
var data =
from subject in subjects
let treatment = this.DbContext.TreatmentFactor.FirstOrDefault(x => x.TreatmentFactorId == subject.ActiveTreatmentFactor)
select new SubjectDataViewModel
{
Name = subject.Name,
Gender = subject.Gender,
Version = subject.Version.IsEnumToValueDisplay() // extented method which displays enum DisplayName property into string
};
return data.AsQueryable();
}
This is the View Model i am populating into as per query above .
public class SubjectDataViewModel
{
public string Name {get;set;}
public string Gender {get;set;}
public string Version {get;set;} // string type return
}
This is Subject Sql View
public class Subjects
{
public string Name {get;set;}
public string Gender {get;set;}
public Version Version {get;set;} // enum return type
}
Enum that is used for Version . Need to Used the ToEnumDiplayValue() extended method in the linq query to pull the Diplay Name i.e Original instead of Database value which is 0 and 1 which will show first or second.
public enum Version
{
[Display(Name = "Original")]
first= 0,
[Display(Name = "Not Original")]
second = 1,
}
So I want to get the DisplayName for the Version which can be done by using our own extended method that using reflection to get the Display name from the enum .
But i cannot use it in the in memoryobject . It has to be converted to .ToList() for.
That is what i want. I hope i am clear. Thank you for your time .
As of now my code will throw ERROR message since i cannot use extended property in Linq.
Try
private IQueryable<SubjectDataViewModel> GetData()
{
var subject = this.DbContext.Subjects.AsQueryable(); //sql view
var data =
from subject in subjects
let treatment = this.DbContext.TreatmentFactor.FirstOrDefault(x => x.TreatmentFactorId == subject.ActiveTreatmentFactor)
select new SubjectDataViewModel
{
Name = subject.Name,
Gender = subject.Gender,
VersionEnum = subject.Version // Version Enum
};
return data.AsQueryable();
}
Use below code to convert GetData() into the list afterwards use IsEnumToValueDisplay() method.
var list = GetData().ToList();
foreach (var item in list)
{
item.Version = item.VersionEnum.IsEnumToValueDisplay(); // Get value from Version Enum
}
Change Model SubjectDataViewModel
public class SubjectDataViewModel
{
public string Name {get;set;}
public string Gender {get;set;}
public Version VersionEnum {get;set;}
public string Version {get;set;}
}
I need the possiblity to create Code in C# like this
public class SummaryA
{
public string name { get; set; }
public string surename { get: set; }
public int age { get; set;}
}
now I create an list object from the class SummaryA
List<SummaryA> list1= new List<SummaryA>();
yet I need the possibility to remove the column age from the list Summary, anyone have ideas?
I need this for some more columns, so I wish the list was dynamically or some things else.
sry for my bad english.
To completely remove the column you really need another class to store the data in, for example:
public class AgelessSummaryA
{
public string name { get; set; }
public string surename { get: set; }
}
And now you can project the first list into a new list of this class with Linq and Select:
List<AgelessSummaryA> agelessSummaries = ageSummaries
.Select(s => new AgelessSummaryA
{
name = s.name,
surename = s.surename
})
.ToList();
To use it for in a grid or for some display i guess, then you can use anonymous types where you can shape the data the way you like:
var projectedList = (from l in list1
select new
{
name = l.name,
surename = l.surename
}).ToList();
public class kDrinki
{
public int id {get; set;}
public string nazwa { get; set; }
public string skladniki { get; set; }
public string opis { get; set; }
public string sciezka { get; set; }
public kDrinki(int _id, string _nazwa, string _skladniki, string _opis, string _sciezka)
{
id = _id;
nazwa = _nazwa;
skladniki = _skladniki;
opis = _opis;
sciezka = _sciezka;
}
}
I have got that class. I created List lst_pDrinkow of object and added some form XML. I don't know how to find only single object (using object id not list id) from list and edit all his data(not only single parameter).
You could try something like this:
var obj = lst_pDrinkow.SingleOrDefault(x=>x.id==Id);
Where Id is the id of the object you are looking for.
If there is an object with the supplied Id, you will get it. Otherwise, the result would be null.
Once you get the object you want, it's very easy to update it's data.
if(obj!=null)
{
obj.nazwa = "new value";
// update the values of the other properties with the same way.
}
Update
While it is not your case, I have to note here that if there are more than one objects with the supplied Id, then you will get an exception. We usually use the SingleOrDefault, when we are sure that the object we are looking for it is unique if at all exists.
More formally:
Returns the only element of a sequence, or a default value if the
sequence is empty; this method throws an exception if there is more
than one element in the sequence.
as it is stated here.
List<kDrinki> items = new List<kDrinki>();
var tmp1 = items.SingleOrDefault(a => a.id == 10);
tmp1.skladniki = "new value";
var tmp2 = items.SingleOrDefault(a => a.opis.Contains("some strings"));
tmp2.skladniki = "new value2";
It's very simple for the user.
They select the type of part, manufacturer from a ComboBox, and search the part code in a text box. Click search and the results return in a DataGridView.
Code:
var mType = CmbType.SelectedItem.ToString();
var mManufacturer = CmbMfr.SelectedValue.ToString();
var mCode = Convert.ToString(TxtProductCode.Text);
switch (mType)
{
case "Faucets":
var faucets = Resources.Accessor.SearchFaucets(mManufacturer, mCode);
DgInventory.DataSource = faucets;
break;
case "Parts":
var parts = Resources.Accessor.SearchParts(mManufacturer, mCode);
DgInventory.DataSource = parts;
break;
}
Accessor Code:
public static List<TblFaucets> SearchFaucets(string mId, string mCode)
{
var dataConnect = new PxLinqSqlDataContext();
return (from f in dataConnect.GetTable<TblFaucets>()
where (f.Mfr == Convert.ToInt32(mId))
where (f.Code == mCode)
select f).ToList<TblFaucets>();
}
What "messes up" is the results:
ID: correct
Mfr: is the ID from its table, not the name
Code: Correct
Description: correct
Price: correct
Date: correct
Manufacturer: I don't know why this is even here, its result is "PXDB.TblManufacturers
First, PXDB.TblManufacturers seems to be a relation from tblFaucets to tblManufactureres.
Mfr seems to be the foreignKey value within your faucets table refering to a manufacturer.
You may try creating an anonymous type holding only those data you want to. Within your select clause pick your data - as well as any relational data.
public static List<DisplayFaucet> SearchFaucets(string mId, string mCode)
{
var dataConnect = new PxLinqSqlDataContext();
return (from f in dataConnect.GetTable<TblFaucets>()
where (f.Mfr == Convert.ToInt32(mId))
where (f.Code == mCode)
select new DisplayFaucet () { // create anonymous object
ID = f.ID, // only holding the data you want to
Manufacturer = Manufacturer.Name, // assuming there is property Name within your manufacturer table?!
Code = f.Code,
Description = f.Description,
Price = f.Price,
Date = f.Date
}).ToList();
}
Add another class to hold your data to display
public class DisplayFaucet
{
public int ID { get; set; }
public string Manufacturer { get; set; }
public string Code { get; set; } // check type
public string Description { get; set; }
public doublePrice{ get; set; } // check type
public DaetTime Date { get; set; } // check type
}
Note that SearchFaucets(..) may no longer return items of type tblFaucet! Instead I created a new class. This one contains all data which should be displayed!
I'm not really sure if what i'm looking for actually exists, so maybe you guys can help out.
I have the below data:
Apples|3211|12
Markers|221|9
Turtle|1023123123|22
The first column is always a string, the second column and third column are ints. However, what I want to do is be able to reference theses as strings or ints, and then be able to sort via the third column asc. Any ideas?
Something like MyTable[i].Column[i] and in this case MyTable[1].Column[2] would produce 12 as a int (because it's ordered).
If you want type safety you will need to create a class that holds each record:
class Record
{
string Name { get; set; }
int SomeValue { get; set; }
int OrderNr { get; set; }
}
Afterwards store them in a generic List<>, then you can order them, as you like:
List<Record> items = // read them into a list of items;
List<Record> orderedList = items.OrderBy(i => i.OrderNr).ToList();
UPDATE
Since it was requested I customized the answer from JustinNiessner to fit to my example:
string data = // your data as string
List<Record> records = data
.Split('|')
.Select(item => new Record
{
Name = item[0],
SomeValue = int.Parse(item[1]),
OrderNr = int.Parse(item[2])
}).ToList();
List<Record> orderedRecords = records.OrderBy(r => r.OrderNr).ToList();
This can be optimized by using var and not executing ToList() on the list, but is done this way in order to keep it simple for you to understand the concepts better.
Assuming you have your data stored in some sort of IEnumerable<string> type, you could try something like:
var sortedObjs = stringRows
.Split('|')
.Select(r => new
{
ColA = r[0],
ColB = int.Parse(r[1]),
ColC = int.Parse(r[2])
})
.OrderBy(r => r.ColC).ToList();
var specificVal = sortedObjs[1].ColC;
This speaks to a larger problem in your design. Using collections to hold a bunch of disparate types with the intent of organizing them into some sort of structure is fragile, error prone, and completely unnecessary.
Instead, create your own type to organize this information.
class MyType
{
public string Name { get; set; }
public int Whatever { get; set; }
public int AnotherProp { get; set; }
}
Now your data is logically grouped in a nice, tight, type safe package.
Your original post didn't specify what the ints were, but since you wanted to select them either by the Descripton(?) or the Id(?) and then sort them by the third column perhaps something like this will work for you?
//Code tested in LinqPad
void Main()
{
//Apples|3211|12
//Markers|221|9
//Turtle|1023123123|22
//Create a list of items
var items = new List<Item>
{
new Item { Description = "Apple", Id = 3211, Sequence = 12 },
new Item { Description = "Markers", Id = 221, Sequence = 9 },
new Item { Description = "Turtle", Id = 1023123123, Sequence = 22 }
};
//Get sorted list of Apple by Description
var sortedByDescription = items.Where(i => i.Description == "Apple").OrderBy(i => i.Sequence);
//Get sorted list of Turtle by Id
var sortedById = items.Where(i => i.Id == 221).OrderBy(i => i.Sequence);
}
public class Item
{
public string Description { get; set; }
public int Id { get; set; }
public int Sequence { get; set; }
}