gpt4 book ai didi

C# 如何将 DbContext.Database.SqlQuery 与抽象/派生类一起使用

转载 作者:太空宇宙 更新时间:2023-11-03 15:06:30 31 4
gpt4 key购买 nike

所以,我的情况是,我使用的是 EF6 和一个组件表,该表使用每个层次结构模式的表。我有一个抽象组件类和一些继承它的类,例如 FirstNameComponent。

调用看起来像这样:

var sql = "Select * from Components";
var components = DbContext.Database.SqlQuery<Component>(sql).ToList();

在这种情况下,我必须使用 SqlQuery 关闭 DbContextDbSet

如您所料,这将查询表中的所有组件并尝试将它们映射到 Component 类,但由于它是抽象的,因此会引发异常。

有没有一种方法可以使用自定义模型绑定(bind)器或表上带有鉴别器列的东西来告诉 SqlQuery 调用每个组件使用哪些类?或者可能采用不同的方式将行序列化/反序列化到组件类中?

最佳答案

您可以在抽象类中定义一个鉴别器属性(基本上是您想要作为鉴别器的列的名称,作为字符串)

比如说,您将 Component 类作为抽象类,而 FirstNameComponent 继承了它。

所以,您希望您的 Component 类看起来像 -

public abstract class Component
{
public const string Discriminator = "ComponentType";

// Other properties/methods
}

现在,您的 FirstNameComponent 类看起来像 -

public class FirstNameComponent : Component
{
public const string TypeOfComponent = nameof(FirstNameComponent);

public override string ComponentType // your discriminator column
{
get
{
return TypeOfComponent;
}
}
// Other properties/methods
}

并在您的上下文中使用 Fluent API 构建模型时使用此属性..

public class ComponentContext: DbContext
{
public DbSet<FirstNameComponent> FirstNameComponents { get; set; }

// Other mappings

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Component>()
.Map<FirstNameComponent>(
configuration =>
configuration.Requires(Component.Discriminator).HasValue(FirstNameComponent.TypeOfComponent))
}
}

因此,您的查询类似于 -

var components = ComponentContext.Components.OfType<FirstNameComponent>();

甚至 -

var components = ComponentContext.Components.Where(c => c is FirstNameComponent).ToList();

更新

查看您更新后的问题,这里是您如何重组查询以获取特定类型的 Component -

string sqlQuery = @"Select * from Components Where ComponentType = @componentType";
string componentType = nameof(FirstNameComponent); //Can be made more dynamic

// Pass the type of component you need to cast to as a parameter
SqlParameter parameter = new SqlParameter("@componentType", componentType);

var components = DbContext.Database.SqlQuery<FirstNameComponent>(sqlQuery, parameter);

这应该会给你想要的结果。

更新 2

所以,在对此进行更多研究之后,我找到了 this讨论使用 Linq to Entities 和 EntitySQL 进行多态查询的博客。

根据引用资料,这是您可以尝试获取所有 Components 的另一种方法 -

string sqlQuery = @"SELECT VALUE c FROM Components AS c";
System.Data.Entity.Core.Objects.ObjectContext objectContext = ((IObjectContextAdapter)ComponentContext).ObjectContext;
System.Data.Entity.Core.Objects.ObjectQuery<Component> objectQuery = objectContext.CreateQuery<Component>(sqlQuery);
List<Component> components = objectQuery.ToList<Component>();

一旦你拥有了所有的Components,你就可以在 ComponentType 字段上使用一个简单的 Where 子句来过滤出所需的类型 -

var firstNameComponents = components.Where(c => c.ComponentType == nameof(FirstNameComponent)).ToList();

关于C# 如何将 DbContext.Database.SqlQuery 与抽象/派生类一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43243593/

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