EF:查询标记为NotMapped的列

问题描述 投票:0回答:1

在 WinForms 应用程序内的 EF DataContext 中,我有多个具有相同布局的表:ID、描述。但是,每个表中的 ID 字段都有不同的名称(“ProductTypeID”、“SubTypeID”、“ProducerID”...)。

我想使用单一表单对此类表进行 CRUD 操作,所以这就是我所做的:

ProductType.csSubType.csProducer.cs

[Table("ProductType")]
public class ProductType : IGenericTable
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductTypeID { get; set; } = -1; // the name of this property is different in every table
    public string Description { get; set; }

    [NotMapped]
    public int ID { get => ProductTypeID; set => ProductTypeID = value; } // used in generic form
}

IGenericTable.cs

internal interface IGenericTable
{
    public int ID { get; set; }
    public string Description { get; set; }
}

GenericForm.cs

internal partial class GenericForm<T> : Form where T : class, IGenericTable, new()
{
    // T.Description property is bound to a textbox.

    private BindingSource bs = new();
    private MODataContext dc;

    public T Item { get => (T)bs.Current; }

    public GenericForm(MODataContext dc, T item)
    {
        InitializeComponent();

        if (item == null) item = new();

        bs.DataSource = item;

        this.dc = dc;
    }

    private void cmdOK_Click(object sender, System.EventArgs e)
    {
        var cur = (T)bs.Current;

        if (cur.ID == -1) dc.Set<T>().Add(cur);

        dc.SaveChanges();

        this.Close();
    }
}

这样我就可以重用相同的表单来创建和编辑所有不同表中的记录。我做了类似查询和删除记录的事情。

我想为具有相同描述的现有记录添加检查

cmdOK_Click
,所以我尝试了以下方法:

    private void cmdOK_Click(object sender, System.EventArgs e)
    {
        var cur = (T)bs.Current;

        var set = dc.Set<T>();

        if (set.Any(x => x.ID != cur.ID && x.Description == txtDescription.Text.Trim())) // EXCEPTION HERE
        {
            MessageBox.Show("A record with the same description already exists!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        if (cur.ID == -1) dc.Set<T>().Add(cur);

        dc.SaveChanges();

        this.Close();
    }

但是这段代码会抛出以下异常: System.NotSupportedException:“LINQ to Entities 不支持指定的类型成员“ID”。仅支持初始值设定项、实体成员和实体导航属性。'

我认为这是因为ID列没有映射到db中的列。 假设我无法更改数据库列名称,我尝试将特定 ID 列和通用 ID 列关联到数据库中的同一列,但这是不允许的:

// This does not work

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), Column("ProductTypeID")]
public int ProductTypeID { get; set; } = -1; // the name of this property is different in every table
public string Description { get; set; }

[Column("ProductTypeID")]
public int ID { get => ProductTypeID; set => ProductTypeID = value; } // used in generic form

在这种情况下,EF 抱怨我不能将两个属性映射到同一列。

有什么线索吗?

c# entity-framework
1个回答
0
投票
if (set.Any(x => x.ID != cur.ID && x.Description == txtDescription.Text.Trim()))

您不能使用 NotMapped 进行查询。通过过滤之前获取数据记录

set.ToList()

© www.soinside.com 2019 - 2024. All rights reserved.