在使用Dapper的Query()函数时,我试图填写一个具有枚举值属性的类.在我的数据库中,此列存储为一个字节.然而,在课堂上,它们是一个枚举.在旧的ADO.NET方法中,我将在阅读器循环期间进行转换:
myClass.myEnum = (MyEnumType) reader.GetByte(2);
Run Code Online (Sandbox Code Playgroud)
使用Dapper时,我无法弄清楚如何进行此转换.例如,当我做类似的事情
myClass = conn.Query<MyClassType>("SELECT ... ")
Run Code Online (Sandbox Code Playgroud)
我收到了类型的错误
Error parsing column 2 (myEnum=1 - Byte)
Run Code Online (Sandbox Code Playgroud)
有没有办法使用Dapper的Query()来填充包含枚举类型属性的类?
是否可以使用Dapper的匿名类型?
我可以看到你如何使用动态ie
connection.Query<dynamic>(blah, blah, blah)
Run Code Online (Sandbox Code Playgroud)
然后可以做一个
.Select(p=> new { A, B ,C })
Run Code Online (Sandbox Code Playgroud)
或之后的一些变化?
编辑
我想我会告诉你我现在如何使用Dapper.我倾向于缓存(使用InMemoryCache)数据,所以我只是在开头做一个大查询(使用Dapper超级快)然后我使用Linq在我的存储库中对它进行排序.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.Linq;
using Dapper;
namespace SomeNamespace.Data
{
public class DapperDataContext : IDisposable
{
private readonly string _connectionString;
private readonly DbProviderFactory _provider;
private readonly string _providerName;
public DapperDataContext()
{
const string connectionStringName = " DataContextConnectionString";
_connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
_providerName = ConfigurationManager.ConnectionStrings[connectionStringName].ProviderName;
_provider = DbProviderFactories.GetFactory(_providerName);
}
public IEnumerable<MyDataView> MyData1 { get; private set; }
public IEnumerable<MyDataView> MyData2 { …Run Code Online (Sandbox Code Playgroud) 我从Nuget(v 1.7)升级到最新版本的Dapper后遇到了一个问题.
它总是返回第一个枚举成员(也就是说,它无法映射).
我使用MySQL作为数据库.
CREATE TABLE `users_roles` (
`userId` INT(11) NOT NULL,
`roleId` INT(11) NOT NULL,
KEY `user_id` (`userId`),
KEY `role_id` (`roleId`)
);
INSERT INTO `users_roles` (`userId`, `roleId`) VALUES (1, 1);
INSERT INTO `users_roles` (`userId`, `roleId`) VALUES (2, 2);
public enum Role {
Anonymous = 0, Authenticate = 1, Administrator = 2
}
var role = Current.Db.Query<Role>(@"SELECT roleId as Role FROM users_roles
WHERE userId=@id", new { id = 2 }).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
它给出了Dapper nuget v1.6中的预期输出.这是新版本(1.7)的正确行为吗?
更新:
在使用一些控制台应用程序和新的mvc3应用程序进行一些测试后,我发现当您直接映射枚举类型时,Dapper枚举映射的行为是不一致的.
但是,将枚举作为类的属性进行映射会以某种方式始终返回正确的映射
public class User
{ …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用dapper的多映射功能来返回相册和相关艺术家和流派的列表.
public class Artist
{
public virtual int ArtistId { get; set; }
public virtual string Name { get; set; }
}
public class Genre
{
public virtual int GenreId { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public …Run Code Online (Sandbox Code Playgroud) 我想了解一个人何时需要考虑使用Dapper.另外,我想了解比较Dapper Vs ADO.NET的优点和缺点
我是新手使用ORM处理数据库,目前我正在制作一个新项目,我必须决定是否使用Entity Framework或Dapper.我读了许多文章说Dapper比实体框架更快.
所以我使用Dapper创建了两个简单的原型项目,另一个使用Entity Framework和一个函数从一个表中获取所有行.表格架构如下图所示

以及两个项目的代码如下
对于Dapper项目
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Emp> emplist = cn.Query<Emp>(@"Select * From Employees");
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
Run Code Online (Sandbox Code Playgroud)
实体框架项目
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
IEnumerable<Employee> emplist = hrctx.Employees.ToList();
sw.Stop();
MessageBox.Show(sw.ElapsedMilliseconds.ToString());
Run Code Online (Sandbox Code Playgroud)
经过多次尝试上面的代码只有我第一次运行项目时,dapper代码会更快,在这第一次之后我总是从实体框架项目中获得更好的结果我还尝试了以下关于实体框架项目的语句来阻止懒惰装载
hrctx.Configuration.LazyLoadingEnabled = false;
Run Code Online (Sandbox Code Playgroud)
但是,除了第一次以外,EF的表现仍然相同.
虽然网上的所有文章都相反,但任何人都能给我解释或指导EF在这个样本中的速度更快
更新
我已经改变了实体样本中的代码行
IEnumerable<Employee> emplist = hrctx.Employees.AsNoTracking().ToList();
Run Code Online (Sandbox Code Playgroud)
使用某些文章中提到的AsNoTracking会停止实体框架缓存,停止缓存后,dapper样本表现更好,(但不是很大的区别)
我试图选择2个整数列的列表将结果映射到元组.举个例子:
return connection.Query<Tuple<int,int>>("select id1, id2 from sometable").ToList();
Run Code Online (Sandbox Code Playgroud)
不起作用,但如果我创建一个具有两个整数的类,相同的查询确实有效,例如:
return connection.Query<BogusClass>("select id1, id2 from sometable").ToList();
public class BogusClass{
public int id1 {get;set;}
public int id2 {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我的偏好不是为了获得一些数据而必须创建一些虚假类.在这种情况下,它是两个整数列,但我还能想到其他用例.
编辑 - 答案:这是HTH的语法
改变:
return connection.Query<Tuple<int,int>>("select id1, id2 from sometable").ToList();
Run Code Online (Sandbox Code Playgroud)
至:
return connection.Query<int, int, Tuple<int, int>>("select id1, id2 from sometable", Tuple.Create, splitOn: "*").ToList();
Run Code Online (Sandbox Code Playgroud) (此代码在C#中使用Dapper Dot Net)
此代码有效:
var command = "UPDATE account SET priority_id = @Priority WHERE name = @Name";
connection_.Execute(command, new { Name = "myname", Priority = 10 } );
Run Code Online (Sandbox Code Playgroud)
此代码抛出SqlException:
class MyAccount
{
public string Name;
public int Priority;
}
var command = "UPDATE account SET priority_id = @Priority WHERE name = @Name";
var acct = new MyAccount { Name = "helloworld", Priority = 10 };
connection_.Execute(command, acct);
Run Code Online (Sandbox Code Playgroud)
System.Data.SqlClient.SqlException:必须声明标量变量"@Priority".
为什么?
我有这样简单的SQL字符串:
"SELECT * FROM Office WHERE OfficeId IN @Ids"
Run Code Online (Sandbox Code Playgroud)
问题是@Ids名称是在编辑器中输入的,所以它可以是任何东西,我的问题是如果我想传入,比如一个整数数组,它只适用于Dapper如果我使用:
var values = new DynamicParameters();
values.AddDynamicParams(new { Ids = new[] { 100, 101 } });
Run Code Online (Sandbox Code Playgroud)
但这需要我知道参数名称是什么Ids,而在我的场景中并非如此.
我可以在Dapper中设置一个"动态参数",其名称为"动态",如下所示:
var values = new DynamicParameters();
values.Add("Ids", new[] { 100, 101 });
Run Code Online (Sandbox Code Playgroud)
但是,然后Dapper不IN (....)为每个值构造具有单独参数的SQL.
有没有办法构建传入的动态对象,AddDynamicParams但事先设置成员名称和值而不知道名称?
我可以修改Dapper源以适应我的场景,但如果有人知道一个更简单和优雅的解决方案,我会很高兴!
我有一个示例模型,如下所示:
public class PersonModel
{
public int Id {get; set;}
public string FirstName {get; set;}
public string Lastname {get; set;}
public string City {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
在我的存储库中,我想创建一个我传入模型的搜索方法 - 但并不是所有字段都会被填充.我想创建一个WHERE和AND,基于是否填充了模型中的字段.如果没有填充该字段,那么我不想为它创建WHERE子句.
例如 - 如果我传入FirstName ="Bob"和City ="Boston",那么我希望我的搜索看起来像这样:
SELECT * FROM PersonTable WHERE FirstName = @firstName AND City = @city
Run Code Online (Sandbox Code Playgroud)
由于我没有传入Id或LastName,我不希望它们添加到查询中.如果我只是通过City ="Boston",那么我希望它看起来像这样:
SELECT * FROM PersonTable WHERE City = @city
Run Code Online (Sandbox Code Playgroud)
我的回购方法看起来像这样
using Dapper;
public List<PersonModel> Search(PersonModel model)
{
//db = DbConnection connection
var selectSql = "SELECT * FROM PersonTable "; //build out where clause …Run Code Online (Sandbox Code Playgroud)