【问题标题】:There has to be a better way to add these using LINQ, right?必须有更好的方法来使用 LINQ 添加这些,对吗?
【发布时间】:2012-11-29 00:23:46
【问题描述】:

我是 LINQ 的新手,并想出了下面的方法来使用 LINQ 和 EF5 向我的数据库添加新信息,但我确信有一种更有效、更好的方法来做到这一点,我只是不知道。我希望得到一些关于我可以做些什么来接受相同但使用更少/更有效的代码的意见。

            using (var db = new FullContext())
            {
                if (ddlItemType.SelectedValue == "Other")
                {
                    var NewItemType = new ItemType { Name = tbNewType.Text };
                    db.ItemTypes.Add(NewItemType);
                    db.SaveChanges();
                }

                if (ddlRegion.SelectedValue == "Other")
                {
                    var NewRegion = new ReleaseRegion { Name = tbNewRegion.Text };
                    db.Regions.Add(NewRegion);
                    db.SaveChanges();


                }

                var NewItemTypeID = byte.Parse((from i in db.ItemTypes
                                                where i.Name == tbNewType.Text
                                                select new { i.ID }).ToString());

                var NewRegionID = byte.Parse((from r in db.Regions
                                              where r.Name == tbNewRegion.Text
                                              select new { r.ID }).ToString());

                var NewItem = new Item
                {
                    Name = tbItemName.Text,
                    TypeID = NewItemTypeID,
                    RegionID = NewRegionID,
                    Condition = ddlCondition.SelectedValue.ToString(),
                    UPC = tbUPC.Text,
                    ISBN = tbISBN.Text,
                    IsColleciton = cbIsCollection.Checked,
                    CollectionID = Convert.ToInt16(ddlCollection.SelectedValue),
                    Notes = tbNotes.Text
                };

                db.Items.Add(NewItem);
                db.SaveChanges();
            }

Item.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace FFCollection.DAL
{
    [Table("Items")]
    public class Item
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Int16 ID { get; set; }

        [Required]
        public string Name { get; set; }

        public byte TypeID { get; set; }

        [ForeignKey("TypeID")]
        public virtual ItemType Type { get; set; }

        public byte RegionID { get; set; }

        [ForeignKey("RegionID")]
        public virtual ReleaseRegion Region { get; set; }

        [Required]
        public string Condition { get; set; }

        public string UPC { get; set; }

        public string ISBN { get; set; }

        public string Notes { get; set; }

        [Required]
        public Boolean IsColleciton { get; set; }

        public Int16 CollectionID { get; set; }

        [ForeignKey("CollectionID")]
        public virtual Item InCollectionID { get; set; }
    }
}

ItemType.cs:

using System.ComponentModel.DataAnnotations.Schema;

namespace FFCollection.DAL
{
    public class ItemType
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public byte ID { get; set; }

        public string Name { get; set; }
    }
}

数据绑定到 DDL:

using (var db = new FullContext())
            {
                ddlItemType.DataSource = (from t in db.ItemTypes
                                          select new { t.ID, t.Name }).ToList();
                ddlItemType.DataTextField = "Name";
                ddlItemType.DataValueField = "ID";
                ddlItemType.DataBind();
                ddlItemType.Items.Insert(0, new ListItem("Other", "Other"));
}

【问题讨论】:

    标签: c# linq entity-framework-5 asp.net-4.5


    【解决方案1】:

    部分问题不在于 Linq,而在于您使用 EF 的方式。基于该示例代码,您将其用作数据层包装器而不是 ORM。在构建对象图时,您应该尽可能处理对象,而不是外键 ID。 ORM 的强大之处在于您可以专门处理映射到数据的对象图,因此当您告诉 ORM 保存对象(及其相关的亲属)时,ORM 会执行插入/更新新对象的所有工作记录和接线键。你在代码中做所有额外的工作,像 EF 这样的 ORM 应该允许你用几行代码完成你想要的。

    首先,在处理组合框时,将它们绑定到包含查找值 ID 的数据结构,您可以解析现有 ItemTypes 或 Regions 的实例以与您的新 Item 关联。 (或在选择“其他”的情况下。

    我要查看的是将组合框绑定到 ItemType/Regions,其中“Other”是一个特定的占位符,如果根据文本字段中的条目进行选择,代码将替换为新对象.然后,无需在附加到“项目”之前保存新对象,您只需设置引用并保存应为新查找对象级联插入操作的项目。

    【讨论】:

    • 不幸的是,我学习 EF 的唯一方法是通过查找非常陈旧、过时的博客/文章来教给自己.我从未使用过 ORM,我只是想将我的网站从 ADO.Net 转换为 EF,而且您第一段的大部分内容对我来说毫无意义。至于组合,它们绑定到 ID/名称对,但“其他”选项是允许人们添加新的区域/类型,我知道这样做的唯一方法是允许 ddl 中的选项并让他们输入一个文本框。如果您知道更好的方法,请告诉我。
    • 我真的很想学习如何做这些事情并正确地做,但我仍然是一名大学学生,我的工作是一名 jr。 dev 不涉及任何使用 EF 的项目。我真正必须学习这些东西的唯一方法是从事自己的家庭项目,在过去几年从事自己的项目时,我了解到通过查看示例并努力适应,我可以很快掌握这些东西他们到我的网站。
    • 不用担心。自己学习技术可能会令人沮丧,但值得付出努力。我指的是多对一的关系。这个链接应该给你一些关于你如何布置你的对象和映射的想法。 stackoverflow.com/questions/11197546/… 在他的示例中,映射相当合理,只是他的问题是恶意初始化。
    • 很高兴您能理解并愿意与我合作。当我在 EF 中创建类时,我将它们设置为 1 对 1 的关系(并且查看 SQL 中的数据库就是这样设置的)其中一个项目只能是一种类型。我没有看过 fulent API,所以链接中的大部分代码对我来说是无法理解的坚持如何清理代码。
    【解决方案2】:

    执行此代码后,EF 会自动将 ID 放入您的 NewItemType 实体中。你不需要再去找它,你可以说NewItemType.ID。这仅在您已经调用 db.SaveChanges() 之后才有效。

    if (ddlItemType.SelectedValue == "Other")
    {
        var NewItemType = new ItemType { Name = tbNewType.Text };
        db.ItemTypes.Add(NewItemType);
        db.SaveChanges();
    }
    

    【讨论】:

    • 所以我只做TypeID = NewItemTypeID而不是TypeID = NewItemType.ID
    • 是的,完全正确。你可以摆脱你调用 byte.Parse 的那个块。
    猜你喜欢
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-14
    • 2019-08-26
    相关资源
    最近更新 更多