Using Dapper, how can I get the value of a column within a table dynamically?
What I have:
string tableName = "Table1";
int itemId = 1;
string columName = "MyBitColumn";
var query = string.Format("select {0} from {1} where {1}Id = #itemId", columnName, tableName);
var entity = conn.Query(query, new { itemId }).FirstOrDefault();
// I'd like something like this...
bool val = entity[columnName] as bool; // returns true or false, given that "MyBitColumn" is a bit in my sql db
Thanks!
You can cast the entity to an IDictionary<string, object> and access by name:
var entity = (IDictionary<string, object>) ... // your code
if((bool)entity[column name]) { ... }
Related
I'm wondering if there is a way to do something like this:
string sql = "SELECT * FROM TABLE WHERE ID = #ID AND VALUE = #VALUE";
var listTest = await _dbConnection.QueryAsync<Example>(sql, ID, VALUE);
I want to query a table with a Composite PK.
var listTest = await _dbConnection.QueryAsync<Example>(sql, new { ID, VALUE });
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
var sql = "Select * FROM CUSTOMERS WHERE CustomerID in #abc";
var affectedRows = connection.Execute(sql, new { abc = 53 });
connection.BulkDelete(connection.Query<Customer>(sql).ToList());
}
The code above cannot work. Instead of directly passing the value inside the query "connection.BulkDelete(connection.Query("Select * FROM CUSTOMERS WHERE CustomerID in (53) ").ToList());", is there any method to pass the flexible value to BulkDelete? Thanks
You are not using the affectedRows:
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
var sql = "Select * FROM CUSTOMERS WHERE CustomerID in #abc";
var affectedRows = connection.Execute<Customer>(sql, new { abc = 53 });
connection.BulkDelete(affectedRows.ToList());
}
I had this relation:
How to retrieve the information in an order entity and invoice entity with a QueryMultiple entity ?
Thanks
QueryMultiple is used when you are accessing multiple result sets, i.e. multiple select, as in:
select * from Order where Id=#id
select * from Invoice where Id = (...probably some sub-query)
At the moment, there is no inbuilt API to stitch this type of query together; instead you would do something like:
using(var multi = conn.QueryMultiple(...)) {
var order = multi.ReadSingle<Order>();
order.Invoice = multi.ReadSingleOrDefault<Invoice>(); // could be null if 0 rows
return order;
}
I would like to add an improved API for this scenario, but it is very awkward to express "join this to that using this property as the association, where {this}.{SomeMember} equals {that}.{SomeOtherMember}".
However, if you are actually doing a single query, as in:
select o.*, i.*
from Order o
left outer join Link l on ...
left outer join Invoice i on ...
where o.Id = #id
then you can use the various Query<,...,> overloads; for example:
int id = ...
var order = conn.Query<Order, Invoice, Order>(sql,
(x,y) => {x.Invoice = y; return x;}, args: new { id }, splitOn: "NumOrder").Single();
Generic code for three tables:
public static Tuple<IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>> ExecuteQueryMultiple<T1, T2, T3>(string sql, object parameters,
Func<GridReader, IEnumerable<T1>> func1,
Func<GridReader, IEnumerable<T2>> func2,
Func<GridReader, IEnumerable<T3>> func3)
{
var objs = getMultiple(sql, parameters, func1, func2, func3);
return Tuple.Create(objs[0] as IEnumerable<T1>, objs[1] as IEnumerable<T2>, objs[2] as IEnumerable<T3>);
}
private static List<object> getMultiple(string procedureName, object param, params Func<GridReader, object>[] readerFuncs)
{
var returnResults = new List<object>();
using (SqlConnection sqlCon = new SqlConnection(connectionString))
{
var gridReader = sqlCon.QueryMultiple(procedureName, param, commandType: CommandType.StoredProcedure);
foreach (var readerFunc in readerFuncs)
{
var obj = readerFunc(gridReader);
returnResults.Add(obj);
}
}
return returnResults;
}
Controller:
[HttpPost]
public ActionResult GetCommodityDetails(int ID)
{
var data = new List<Commodity>();
DynamicParameters param = new DynamicParameters();
param.Add("#ATTRIBUTETYPE", "Your parameter");
param.Add("#CID", Your parameter);
var result = DapperORM.ExecuteQueryMultiple("Store procedure name", param, gr => gr.Read<order>(), gr => gr.Read<Invoice>(), gr => gr.Read<Link>());
return Json(result, JsonRequestBehavior.AllowGet);
}
You can use this concept. It worked for me
I use c# and ef4.
I have a Model with an Entity with two proprieties int Id and string Title.
I need to write an ESQL query that is able to return bool TRUE if Id and Title are present in the DataSource. Please note Id is a PrimaryKey in my data storage.
Any idea how to do it?
You can do it by each code-snippets below:
1)
using (YourEntityContext context = new YourEntityContext ()) {
var queryString =
#"SELECT VALUE TOP(1) Model FROM YourEntityContext.Models
As Model WHERE Model.Id = #id AND Model.Title = #title";
ObjectQuery<Model> entityQuery = new ObjectQuery<Model>(queryString, context);
entityQuery.Parameters.Add(new ObjectParameter("id", id));
entityQuery.Parameters.Add(new ObjectParameter("title", title));
var result = entityQuery.Any();
}
2)
using (YourEntityContext context = new YourEntityContext ()) {
ObjectQuery<Model> entityQuery =
context.Models
.Where("it.Id = #id AND it.Title = #title"
, new ObjectParameter("id", id)
, new ObjectParameter("title", title)
);
var result = entityQuery.Any();
}
3)
var context = new YourEntityContext();
using (EntityConnection cn = context.Connection as EntityConnection) {
if (cn.State == System.Data.ConnectionState.Closed)
cn.Open();
using (EntityCommand cmd = new EntityCommand()) {
cmd.Connection = cn;
cmd.CommandText = #"EXISTS(
SELECT M FROM YourEntityContext.Models as M
WHERE M.Id == #id AND Model.Title = #title
)";
cmd.Parameters.AddWithValue("id", _yourId);
cmd.Parameters.AddWithValue("title", _yourTitle);
var r = (bool)cmd.ExecuteScalar();
}
}
4)
using (YourEntityContext context = new YourEntityContext ()) {
var queryString =
#"EXISTS(
SELECT M FROM YourEntityContext.Models as M
WHERE M.Id == #id AND Model.Title = #title
)";
ObjectQuery<bool> entityQuery = new ObjectQuery<bool>(queryString, context);
entityQuery.Parameters.Add(new ObjectParameter("id", id));
entityQuery.Parameters.Add(new ObjectParameter("title", title));
var result = entityQuery.Execute(MergeOption.AppendOnly).FirstOrDefault();
}
4 is the best way I suggest you. Good lock
What javad said is true, but another way is:
bool result = entities.Any(x=>x.Id == id && x.Title == title) ;
In fact because Id is primary key, DB prevent from occurrence of this more than one time .
Using LINQ I would like to sort by the passed in int arrays index.
So in the code below attribueIds is my int array. I'm using the integers in that array for the where clause but I would like the results in the order that they were in while in the array.
public List BuildTable(int[] attributeIds)
{
using (var dc = new MyDC())
{
var ordering = attributeIds.ToList();
var query = from att in dc.DC.Ecs_TblAttributes
where attributeIds.Contains(att.ID)
orderby(ordering.IndexOf(att.ID))
select new Common.Models.Attribute
{
AttributeId = att.ID,
DisplayName = att.DisplayName,
AttributeName = att.Name
};
return query.ToList();
}
}
I would recommend selecting from the attributeIDs array instead. This will ensure that your items will be correctly ordered without requiring a sort.
The code should go something like this:
var query =
from id in attributeIds
let att = dc.DC.Ecs_TblAttributes.FirstOrDefault(a => a.ID == id)
where att != null
select new Common.Models.Attribute
{
AttributeId = att.ID,
DisplayName = att.DisplayName,
AttributeName = att.Name
};
Why don't you join:
public List BuildTable(int[] attributeIds)
{
using (var dc = new MyDC())
{
var query = from attID in attributeIds
join att in dc.DC.Ecs_TblAttributes
on attID equals att.ID
select new Common.Models.Attribute
{
AttributeId = attID,
DisplayName = att.DisplayName,
AttributeName = att.Name
};
return query.ToList();
}
}