AsEnumerable()
IQueryable()
使用更安全(例如,它是否已作为ToList()
执行),以便为错误automapper Only parameterless constructors and initializers are supported in LINQ to Entities.
找到解决方法(见下文) ?
换句话说,在AsEnumerable()
上使用IQueryable()
会产生什么影响,尤其是在将Where()
链接到它时。
请阅读以下内容,了解完整背景和信息。
我正在为我的存储库层实现抽象,因为我必须能够从JSON文件,XML文件以及EntityFramework(数据库)中读取数据。
在执行这样的代码时,我在使用错误automapper Only parameterless constructors and initializers are supported in LINQ to Entities.
投影我的EF实体时遇到了问题:
public IEnumerable<Person> All() {
return _dataContext
.People
.Select(p => new Person(p.Id, p.FirstName, p.LastName));
}
作为参考,这是我的DbContext
,因此您看到以上_dataContext.People
返回IQueryable<EFPerson>
:
public class EFDataContext : DbContext
{
public IDbSet<EFPerson> People { get; set; }
public EFDataContext()
: this(Settings.Default.EFDataContextConnectionString) { }
public EFDataContext(string nameOrConnectionString)
: this(() => nameOrConnectionString) { }
public EFDataContext(Func<string> connectionStringProvider)
: base(connectionStringProvider()) { }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<EFPerson>()
.HasKey(p => p.Id)
.ToTable(Settings.Default.PeopleTable);
}
}
我不想使用AutoMapper
,我也不想让我的域名实体拥有setters
- 因为他们需要对商业模式我来说是不可变的/只读的写作。
我想出的解决方案是使用.AsEnumerable()
,然后使用我的域实体的构造函数进行投影:
public IEnumerable<Person> All() {
return _dataContext
.People
.AsEnumerable()
.Select(p => new Person(p.Id, p.FirstName, p.LastName));
}
代码运行得很快,之后我也可以在域实体上进行.Where
预测。 我认为这是安全的,因为我的理解是.AsEnumerable
不会像.ToList
那样立即评估。
我的问题因此,我的假设是正确的。这样做是否是一种安全的解决方法,或者我应该对它进行不同的建模 - 使用AutoMapper还是在我的服务层/存储库的EntityFramework实现中编写更长的逻辑?
答案 0 :(得分:1)
由于你的问题非常广泛,我将描述我的解决方案: 在Entity Framework中使用您的域实体:
public class EFDataContext : DbContext
{
public IDbSet<Person> People { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Person>()
.HasKey(p => p.Id)
.ToTable(Settings.Default.PeopleTable);
}
}
根据需要设计实体:
public class Person
{
private Person() //for EF
{
}
public Person(string name) //for me
{
Name = name;
}
public int Id { get; private set; }
public string Name { get; private set; }
public string LastName { get; private set; }
}
查询:
public IEnumerable<Person> All() {
return _dataContext
.People
.AsEnumerable();
}
为什么我在这里使用AsEnumerable
?只是为了隐藏我的数据库及其IQueryable
。
如您所见,EF允许使用域对象。