Is there an option to have dapper throw an error if the Query method fails to find a property matching a returned column in a result set?
For example:
public class Person{
public String FirstName {get; set;}
public String LastName {get; set;}
}
...
conn.Query<Person>("select FName, LName from Users");
The above would throw no error despite that no data was transferred due to the name mismatch.
If not is there a reason not to add it? My old home-grown micro-ORM did this and I miss the feature so I'd consider attempting to add it, but not if there were specific design decisions that already eliminated it (ie "raw performance").
I ended up using a chunk of code called SafeDapper:
https://github.com/LarrySmith-1437/SafeDapper
Different naming property you must be manual mapping.
Install Dapper.FluentMap NuGet package.
Manual mapping
public class PersonMap : EntityMap<Person>
{
public PersonMap()
{
// Map property 'FirstName' to column 'FName'.
Map(p => p.FirstName)
.ToColumn("FName");
// Map property 'FirstName' to column 'FName'.
Map(p => p.LastName)
.ToColumn("LName");
}
}
Initialization:
FluentMapper.Initialize(config =>
{
config.AddMap(new PersonMap());
});
Related
I've faced the problem with Dapper FluentMap (version 1.60) which I don't know how to fix. It looks like Dapper can't map a column from a table if the corresponding property in .NET class has "Date" name.
I have the table in DB (I'm using MS SQL if that's matter) with column Dt of Date type.
There is an entity with DateTime property:
public class MyEntity {
public DateTime Date { get; set; }
}
and the corresponding mapping:
public class MyEntityMapper : EntityMap<MyEntity> {
public MyEntityMapper() {
Map(p => p.Date).ToColumn("Dt");
}
}
When I try to get data from the DB and map to MyEntity, I get the following error:
ArgumentNullException: Value cannot be null. Parameter name: meth
If I rename Date property in MyEntity to something else like Dt or JustDate - everything works fine. Is there such restriction in Dapper Fluent Map (not allowed to give a name to property equal to data type name in DB)?
If so, is it possible to overcome it somehow? Because in my case it's a bit problematic to rename property in MyEntity
Yes you are right, the only solution you can do was to change your entity property Date into other name.
I am trying to create a package containing several Data Flow tasks in them. The tasks are fairly similar in nature, but contain fairly important differences.
I have tried to copy the task, then change the things which need changing.
When I run the task by itself it runs fine, however when I run it with all the other tasks in the package I get the below error:
Object reference not set to an instance of an object. at
ScriptMain.Input0_ProcessInputRow(Input0Buffer Row) at
UserComponent.Input0_ProcessInput(Input0Buffer Buffer) at
UserComponent.ProcessInput(Int32 InputID, String InputName,
PipelineBuffer Buffer, OutputNameMap OutputMap) at
Microsoft.SqlServer.Dts.Pipeline.ScriptComponent.ProcessInput(Int32
InputID, PipelineBuffer buffer) at
Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost.ProcessInput(Int32
inputID, PipelineBuffer buffer)
Not the most friendly error message.
Can anyone tell me what this is and how to fix it? I assume that there is some variable or other attribute which is being repeated, but which one?
Note that many of the columns over the several data flow tasks will have the same column names.
I figured it out in the end. The reason was that the second level objects need to be explicitly declared.
I had
public class Level2
{
public string Somevalue { get; set; }
}
public class RootAttributes
{
public Level2 lvl2 { get; set; }
public string Somevalue2 { get; set; }
}
It should have been
public class Level2
{
public string Somevalue { get; set; }
}
public class RootAttributes
{
public Level2 lvl2 = new Level2;
public string Somevalue2 { get; set; }
}
The weird thing was that the top method worked in several other places.
I had this issue with my send mail task.
As I was using a file connection for my body of the email, I had to create a new file connection and it worked fine.
Use the package run report in vs 2012 to identify in which DFT task package got failed.
Use the view code option of the package to see the whether all the DFT task having proper input.
I'm seeing a very bizarre issue with iBatis when trying to read a property from a Java map using isEqual, but not with other iBatis operators. For example it is able to read the map properties fine when using isNotNull and iterate. The xml:
<isNotNull property="filterCriteria.account">
AND
id
<isEqual property="filterCriteria.account.meetsCriteria" compareValue="false">
NOT
</isEqual>
IN
(SELECT DISTINCT id
FROM account
WHERE some other criteria....
)
</isNotNull>
The 2 java classes we're using here:
public class SearchProfile {
private Map<String, SearchProfileCriteria> filterCriteria;
public SAOSearchProfile() {
filterCriteria = new HashMap<>();
}
public Map<String, SAOSearchProfileCriteria> getFilterCriteria() {
return filterCriteria;
}
public void setFilterCriteria(Map<String, SAOSearchProfileCriteriaBase> filterCriteria) {
this.filterCriteria = filterCriteria;
}
}
Above is the container object that is passed to iBatis for the querying, and below is the criteria object that will be the value of the map. In this example it is keyed with the String "account"
public class SearchProfileCriteria {
boolean meetsCriteria;
public String getCriteriaAsString() {
return StringUtils.getStringValueFromBoolean(meetsCriteria);
}
public boolean isMeetsCriteria() {
return meetsCriteria;
}
public void setMeetsCriteria(boolean meetsCriteria) {
this.meetsCriteria = meetsCriteria;
}
public String getSQLString(){
return meetsCriteria ? "" : "NOT";
}
}
And the exception:
Cause: com.ibatis.common.beans.ProbeException: There is no READABLE property named 'account' in class 'java.util.Map'; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
The getSQLString() method was my half baked attempt at a work around, the String gets escaped in the query and throws a syntax error.
When I remove the <isEqual> block the query executes find, which indicates it is able to read the "account" key when checking the to see if it is null. As I mentioned above, we're also able to use the map keys in <iterate> tags without issue. It seems <isEqual> and <isNotEqual> are the only tags causing issues. Does anyone have experience with this or know what may be going on?
Beware: Using isNotNull, isEqual, iterate is iBatis, they don't exist anymore in Mybatis, so referencing to Mybatis indifferently is confusing.
Reference documentation.
For your issue, how does it behave if replacing Map with a class (property will be known at compile time)?
Or try using <isPropertyAvailable>.
The work around could work with right syntax: $ instead of #: $filterCriteria.account.SQLString$ instead of #filterCriteria.account.SQLString#, then the value is just concatenated instead of bound as parameter.
I tried to play with Dapper Extension & MS Access and succeeded up to certain extent. My code is listed below. All the functions works properly (Insert/Count/GetList/Delete) except Get & Update. I have summarised the code below. If anybody wants I can paste all the code here
My Product class
public class Products
{
public string ProductNumber { get; set; }
public string Description { get; set; }
}
And in my main class. I tried to get the product and update it as below. con.Get<Products> function returns an exception with "Sequence contains more than one element" message and con.Update<Products> returns an exception with "At least one Key column must be defined".
using (var con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb"))
{
string ProductNumber = "12";
var product4 = con.Get<Products>(ProductNumber);
product4.ProductNumber = "Baz";
con.Update<Products>(product4);
Console.ReadLine();
}
Even though con.Get<Products> fails con.GetList<Products>(predicate) works perfectly. I did follow this link for setup
If DapperExtensions can't infer a key property called ID from your class, you'll need to explicitly specify one via a class mapper. Assuming the ProductNumber is the primary key in the database, the following example class mapper should set the ProductNumber to be the primary key for DapperExtensions.
using Dapper;
using DapperExtensions;
using DapperExtensions.Mapper;
public class ProductsMapper : ClassMapper<Products>
{
public ProductsMapper()
{
Map(x => x.ProductNumber).Key(KeyType.Assigned);
AutoMap();
}
}
This class can sit somewhere within the same assembly as the rest of your code. Dapper Extensions will automatically pick it up. If you have your classes and Dapper code in separate assemblies, you can point it to your mapper with the following line:
DapperExtensions.DapperExtensions.SetMappingAssemblies({ typeof(ProductsMapper).Assembly })
I have set up my first project using FluentNHibernate. When I tried to get a list of records from a single table, I got an exception which says:
System.FormatException : String was not recognized as a valid Boolean.
The problem is that in the database table, there is a column called "flag" and its data type is char, but it only contains values of either '0' or '1'. So, I'd like to map it to type bool in my POCO:
public class Students
{
public virtual int Id {get; private set;}
public virtual string FirstName {get; set;}
public virtual string LastName {get; set;}
public virtual DateTime RegisterDate {get; set;}
public virtual bool Flag {get; set;}
}
Now, in my Mappings.cs, how do I convert Flag to bool?
public class StudentMap : ClassMap<Students> {
public StudentMap() {
Id(x => x.Id);
Map(x => x.FirstName).Column("first_name");
Map(x => x.LastName).Column("last_name");
Map(x => x.RegisterDate).Column("register_date");
Map(x => x.Flag); // This won't work because
// column "flag" is char,
// whereas x.Flag is bool.
}
}
That's question 1.
Also, in the database, the table name is "students", but in my business model, I want to use the singular as Student, how can I do this? Right now, if I define my business class as Student, I will get an error which says something like the table "student" is not found.
The database is MySQL, if that matters.
Thanks for your hint.
For part 1, use this on your app.config/nhibernate.config/whateverYourNHibernateConfigFile
<property name="query.substitutions">true 1, false 0</property>
Edit after comment:
If you're using fluent nhibernate, just uses its API, example
var props = new Dictionary<string, string>();
props.Add("query.substitutions","true 1, false 0");
var sessionFactory = Fluently.Configure().BuildConfiguration().AddProperties(props);
For part 1, in your configuration object, you need to set the query.substitutions property to true=1, false=0.
For part 2, there should be a Table("") method you can use to specify the table name in the StudentMap class.