gpt4 book ai didi

c# - 如何在 Linq-to-SQL 实体类中创建自定义属性?

转载 作者:太空宇宙 更新时间:2023-11-03 13:58:05 25 4
gpt4 key购买 nike

我有两个表 Studies 和 Series。系列 FK'd 回到研究,因此一项研究包含可变数量的系列。每个 Series 项目都有一个 Deleted 列,表明它已从数据库中逻辑删除。

我正在尝试在 Study 类中实现一个 Deleted 属性,该属性仅在删除所有包含的 Series 时才返回 true。我正在使用 O/R Designer 生成的类,因此我将以下内容添加到 Study 类型的用户可修改分部类中:

public bool Deleted
{
get
{
var nonDeletedSeries = from s in Series
where !s.Deleted
select s;
return nonDeletedSeries.Count() == 0;
}
set
{
foreach (var series in Series)
{
series.Deleted = value;
}
}
}

这给出了一个异常“成员‘PiccoloDatabase.Study.Deleted’没有支持的 SQL 转换。”当执行这个调用 get 的简单查询时:

IQueryable<Study> dataQuery = dbCtxt.Studies;
dataQuery = dataQuery.Where((s) => !s.Deleted);
foreach (var study in dataQuery)
{
...
}

基于此http://www.foliotek.com/devblog/using-custom-properties-inside-linq-to-sql-queries/ ,我尝试了以下方法:

static Expression<Func<Study, bool>> DeletedExpr = t => false;
public bool Deleted
{
get
{
var nameFunc = DeletedExpr.Compile();
return nameFunc(this);
}
set
{ ... same as before
}
}

当运行查询时,我遇到了同样的异常,即没有支持的 SQL 转换。 (lambda 表达式的逻辑还无关紧要 - 只是试图绕过异常。)

我是否遗漏了一些基本属性或允许转换为 SQL 的内容?我已经阅读了 SO 上关于此异常的大部分帖子,但似乎没有任何内容完全适合我的情况。

最佳答案

我相信 LINQ-to-SQL 的要点是您的实体已为您映射并且必须在数据库中具有相关性。看来您正在尝试混合使用 LINQ-to-Objects 和 LINQ-to-SQL。

如果 Series 表在数据库中有 Deleted 字段,而 Study 表没有,但您想将逻辑 Study.Deleted 转换为 SQL,那么扩展将是一种方法。

public static class StudyExtensions
{
public static IQueryable<study> AllDeleted(this IQueryable<study> studies)
{
return studies.Where(study => !study.series.Any(series => !series.deleted));
}
}

class Program
{
public static void Main()
{
DBDataContext db = new DBDataContext();
db.Log = Console.Out;

var deletedStudies =
from study in db.studies.AllDeleted()
select study;

foreach (var study in deletedStudies)
{
Console.WriteLine(study.name);
}
}
}

这会将您的“已删除研究”表达式映射到 SQL 中:

SELECT t0.study_id, t0.name
FROM study AS t0
WHERE NOT EXISTS(
SELECT NULL AS EMPTY
FROM series AS t1
WHERE (NOT (t1.deleted = 1)) AND (t1.fk_study_id = t0.study_id)
)

或者,您可以构建实际的表达式并将它们注入(inject)到您的查询中,但这是一种矫枉过正的做法。

但是,如果 Series 和 Study 在数据库中都没有 Deleted 字段,而只在内存中,那么您需要先将查询转换为 IEnumerable,然后才能访问 Deleted 属性。然而,这样做会在应用谓词之前将记录传输到内存中,并且可能会很昂贵。即

var deletedStudies = 
from study in db.studies.ToList()
where study.Deleted
select study;

foreach (var study in deletedStudies)
{
Console.WriteLine(study.name);
}

关于c# - 如何在 Linq-to-SQL 实体类中创建自定义属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11526377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com