C# LINQ,在映射中实现接口和异常的实体
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LINQ, entity that implements Interface and exception in mapping
提问by Hrvoje Hudo
I'm using repository pattern with LINQ, have IRepository.DeleteOnSubmit(T Entity). It works fine, but when my entity class has interface, like this:
我在 LINQ 中使用存储库模式,有 IRepository.DeleteOnSubmit(T Entity)。它工作正常,但是当我的实体类具有接口时,如下所示:
public interface IEntity { int ID {get;set;} }
public partial class MyEntity: IEntity {
public int ID {
get { return this.IDfield; }
set { this.IDfield=value; }
}
}
and then trying to delete some entity like this:
然后尝试删除一些这样的实体:
IEntity ie=repository.GetByID(1);
repoitory.DeleteOnSubmit(ie);
throws
The member 'IEntity.ID' has no supported translation to SQL.
throws
成员“IEntity.ID”不支持转换为 SQL。
fetching data from DB works, but delete and insert doesn't. How to use interface against DataContext?
从数据库中获取数据有效,但删除和插入无效。如何针对 DataContext 使用接口?
Here it is:
Exception message:
The member 'MMRI.DAL.ITag.idContent' has no supported translation to SQL.
它是:
异常消息:成员“MMRI.DAL.ITag.idContent”不支持转换为 SQL。
Code:
代码:
var d = repContent.GetAll().Where(x => x.idContent.Equals(idContent));
foreach (var tagConnect in d) <- error line
{
repContet.DeleteOnSubmit(tagConnect);
(it gets all tags from DB, and deletes them)
(它从数据库中获取所有标签,并删除它们)
And stack trace:
和堆栈跟踪:
[NotSupportedException: The member 'MMRI.DAL.ITag.idContent' has no supported translation to SQL.]
System.Data.Linq.SqlClient.Visitor.VisitMember(SqlMember m) +621763
System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +541
System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp) +8
System.Data.Linq.SqlClient.SqlVisitor.VisitBinaryOperator(SqlBinary bo) +18
System.Data.Linq.SqlClient.Visitor.VisitBinaryOperator(SqlBinary bo) +18
System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +196
System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp) +8
System.Data.Linq.SqlClient.SqlVisitor.VisitSelectCore(SqlSelect select) +46
System.Data.Linq.SqlClient.Visitor.VisitSelect(SqlSelect select) +20
System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +1024
System.Data.Linq.SqlClient.SqlProvider.BuildQuery( ...
When I try do decorate partial class:
当我尝试装饰部分类时:
[Column(Storage = "_idEvent", DbType = "Int NOT NULL", IsPrimaryKey = true)]
public int idContent
{ get { return this.idEvent; } set { this.idEvent=value; } }
it throws error "Invalid column name 'idContent'."
它抛出错误“无效的列名‘idContent’。”
回答by Mark Cidade
Try this:
尝试这个:
using System.Data.Linq.Mapping;
public partial class MyEntity: IEntity
{ [Column(Storage="IDfield", DbType="int not null", IsPrimaryKey=true)]
public int ID
{
get { return this.IDfield; }
set { this.IDfield=value; }
}
}
回答by Frank Tzanabetis
This works for me -
这对我有用-
public partial class MyEntity: IEntity
{ [Column(Name = "IDfield", Storage = "_IDfield", IsDbGenerated = true)]
public int ID
{
get { return this.IDfield; }
set { this.IDfield=value; }
}
}
回答by jeroenh
For translating your LINQ query to actual SQL, Linq2SQL inspects the expression you give it. The problem is that you have not supplied enough information for L2S to be able to translate the "ID" property to the actual DB column name. You can achieve what you want by making sure that L2S can map "ID" to "IDField".
为了将您的 LINQ 查询转换为实际的 SQL,Linq2SQL 会检查您提供的表达式。问题是您没有为 L2S 提供足够的信息,无法将“ID”属性转换为实际的 DB 列名称。您可以通过确保 L2S 可以将“ID”映射到“IDField”来实现您想要的。
This should be possible using the approach provided in answers.
使用答案中提供的方法应该可以做到这一点。
If you use the designer, you can also simply rename the class property "IDField" to "ID", with the added benefit that you won't have to explicitly implement the "ID" property in your partial class anymore, i.e. the partial class definition for MyEntity simply becomes:
如果您使用设计器,您还可以简单地将类属性“IDField”重命名为“ID”,另外的好处是您不必再在分部类中显式实现“ID”属性,即分部类MyEntity 的定义简单地变为:
public partial class MyEntity: IEntity
{
}
回答by jahu
It appears Microsoft dropped support for ==
operator in interfaces when using linq-to-sql in MVC4 (or maybe it was never supported). You can however use i.ID.Equals(someId)
in place of the ==
operator.
==
在 MVC4 中使用 linq-to-sql 时,微软似乎放弃了对接口中的运算符的支持(或者它可能从未被支持)。但是i.ID.Equals(someId)
,您可以代替==
操作符使用。
Casting IQueryable
to IEnumerable
works but should not be used!The reason is: IQueryable
has funky implementation of IEnumerable
. Whatever linq method you'll use on a IQueryable
through the IEnumerable
interface will cause the query to be executed first, have all the results fetched to the memory from the DB and eventually running the method localy on the data (normally those methods would be translated to SQL and executed in the DB). Imagine trying to get a single row from a table containing billion rows, fetching all of them only to pick one (and it gets much worse with careless casting of IQueryable
to IEnumerable
and lazy loading related data).
投射IQueryable
到IEnumerable
作品但不应该使用!原因是:IQueryable
具有时髦的IEnumerable
. 无论您将IQueryable
在IEnumerable
接口上使用什么 linq 方法,都将首先执行查询,将所有结果从数据库提取到内存中,并最终在数据本地运行该方法(通常这些方法将被转换为 SQL并在数据库中执行)。想象一下,试图从一个包含 10 亿行的表中获取一行,获取所有这些行只是为了选择一个(如果不小心转换IQueryable
toIEnumerable
和延迟加载相关数据,情况会变得更糟)。
Apparently Linq has no problem using ==
operator with interfaces on local data (so only IQueryable
is affected) and also with Entity Frameworks (or so I heard).
显然,Linq==
在本地数据上使用带有接口的操作符(所以只IQueryable
受影响)和实体框架(或者我听说过)没有问题。