在 Linq2SQL 中创建条件关系

发布于 2024-12-04 10:21:16 字数 672 浏览 0 评论 0原文

我正在对旧数据库系统使用 linq2sql。该系统中有三个表:Invoices、Users 和 SignupUsers。 Invoices 表有一个 UID 字段,通常引用 Users 表上的 UID 键。但是,它还有一个 IsSignup 位字段,指示 UID 字段应引用 SignupUsers 表上的 UID 键。

我并不真正关心与 SignupUsers 表的关系,但我们确实有一个问题,即在使用 linq2sql 实体时很容易忘记检查“IsSignup”值。我想使实体中的发票->用户关系以 IsSignup 位字段为条件。

我尝试了几种方法。首先,我尝试设置 OnLoaded:

public partial class Invoice
{
    partial void OnLoaded()
    {
        if (IsSignup)
        {
            InvoiceUser = null;
        }
    }
}

这失败了,因为它在保存发票时尝试将 UID 字段实际设置为 null - 这是我们无法做到的。

我研究了 DataLoadOptions,但也找不到一种方法来实现这一点。

我可以只更改 InvoiceUsers 属性 getter,但每次 dbml 更改时它都会被覆盖。

我只是运气不好吗?

I'm using linq2sql against an old database system. In this system there are three tables, Invoices, Users, and SignupUsers. The Invoices table has a UID field that usually references the UID key on the Users table. BUT, it also has a IsSignup bit field that indicates the UID field should reference the UID key on the SignupUsers table.

I don't really care about the relationship with the SignupUsers table, but we do have a problem where it is very easy to forget to check the "IsSignup" value when using the linq2sql entities. I'd like to make the Invoices->Users relationship in the entities conditional upon the IsSignup bit field.

I've tried a couple of approaches. First I tried setting up OnLoaded:

public partial class Invoice
{
    partial void OnLoaded()
    {
        if (IsSignup)
        {
            InvoiceUser = null;
        }
    }
}

This fails because it tries to actually set the UID field to null when it saves the invoice back-- which we cannot do.

I poked around with DataLoadOptions, but couldn't find a way to make that work either.

I could just change the InvoiceUsers property getter, but then it'd get overwritten every time the dbml gets changed.

Am I just out of luck here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

桜花祭 2024-12-11 10:21:16

我将在这里提出我的解决方案,但仍然希望有人能提出更好的解决方案。

我使用 T4 的 LINQ to SQL 模板 生成代码。我进入了这个特定 .dbml 文件的 .tt 文件,找到了生成关系属性的部分。然后,我在“if”语句中进行了修改,如果该属性应用于此特定关系,则修改该属性:

    <#=code.Format(association.MemberAttributes)#><#=association.Type.Name#> <#=association.Member#>
    {
        get {
            <#if(association.Name == "InvoiceUser_Invoice"){#>
                            //HACK IN THE .TT FILE TO ALWAYS INCLUDE THIS CONDITIONAL RELATIONSHIP
            if(IsSignup){return null;}
            <#}#>
            <#if (needsSerializationFlag && serialization) {#>
            if (serializing && !<#=association.Storage#>.HasLoadedOrAssignedValue) {
                return null;
            }
            <#}#>
            return <#=association.Storage#>.Entity;
        }

这使得该特定属性的生成代码按预期输出:

    [Association(Name=@"InvoiceUser_Invoice", Storage=@"_InvoiceUser", ThisKey=@"UID", OtherKey=@"UID", IsForeignKey=true)]
    public InvoiceUser InvoiceUser
    {
        get {
            //HACK IN THE .TT FILE TO ALWAYS INCLUDE THIS CONDITIONAL RELATIONSHIP
                            if(IsSignup){return null;}
                            return _InvoiceUser.Entity;
        }
        set {
            InvoiceUser previousValue = _InvoiceUser.Entity;
            if ((previousValue != value) || (!_InvoiceUser.HasLoadedOrAssignedValue)) {
                SendPropertyChanging();
                if (previousValue != null) {
                    _InvoiceUser.Entity = null;
                    previousValue.Invoices.Remove(this);
                }
                _InvoiceUser.Entity = value;
                if (value != null) {
                    value.Invoices.Add(this);
                    _UID = value.UID;
                }
                else {
                    _UID = default(int);
                }
                SendPropertyChanged("InvoiceUser");
            }
        }
    }

所以仍然是一个令人讨厌的黑客,但它至少可以防止对 . dbml 文件中删除所需的条件关系。

I'll put in my solution here, but still hope someone can come up with something better.

I'm using LINQ to SQL templates for T4 to generate the code. I went into the .tt file for this particular .dbml file and found the portion that generates the properties for the relationships. I then hacked in an "if" statement that modified the property if it applied to this particular relationship:

    <#=code.Format(association.MemberAttributes)#><#=association.Type.Name#> <#=association.Member#>
    {
        get {
            <#if(association.Name == "InvoiceUser_Invoice"){#>
                            //HACK IN THE .TT FILE TO ALWAYS INCLUDE THIS CONDITIONAL RELATIONSHIP
            if(IsSignup){return null;}
            <#}#>
            <#if (needsSerializationFlag && serialization) {#>
            if (serializing && !<#=association.Storage#>.HasLoadedOrAssignedValue) {
                return null;
            }
            <#}#>
            return <#=association.Storage#>.Entity;
        }

This makes the generated code for that particular property come out as desired:

    [Association(Name=@"InvoiceUser_Invoice", Storage=@"_InvoiceUser", ThisKey=@"UID", OtherKey=@"UID", IsForeignKey=true)]
    public InvoiceUser InvoiceUser
    {
        get {
            //HACK IN THE .TT FILE TO ALWAYS INCLUDE THIS CONDITIONAL RELATIONSHIP
                            if(IsSignup){return null;}
                            return _InvoiceUser.Entity;
        }
        set {
            InvoiceUser previousValue = _InvoiceUser.Entity;
            if ((previousValue != value) || (!_InvoiceUser.HasLoadedOrAssignedValue)) {
                SendPropertyChanging();
                if (previousValue != null) {
                    _InvoiceUser.Entity = null;
                    previousValue.Invoices.Remove(this);
                }
                _InvoiceUser.Entity = value;
                if (value != null) {
                    value.Invoices.Add(this);
                    _UID = value.UID;
                }
                else {
                    _UID = default(int);
                }
                SendPropertyChanged("InvoiceUser");
            }
        }
    }

So still a nasty hack, but it at least prevents changes to the .dbml file from removing the needed conditional relationship.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文